| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647 |
- # $Id: 98_STOCKQUOTES.pm 12272 2016-10-04 16:15:45Z vbs2 $
- package main;
- use strict;
- use warnings;
- use Blocking;
- use Finance::Quote;
- use Encode qw(decode encode);
-
- sub STOCKQUOTES_Initialize($)
- {
- my ($hash) = @_;
- $hash->{DefFn} = "STOCKQUOTES_Define";
- $hash->{UndefFn} = "STOCKQUOTES_Undefine";
- $hash->{SetFn} = "STOCKQUOTES_Set";
- $hash->{GetFn} = "STOCKQUOTES_Get";
- $hash->{AttrFn} = "STOCKQUOTES_Attr";
- $hash->{AttrList} = "pollInterval queryTimeout defaultSource sources stocks currency $main::readingFnAttributes";
- }
- sub STOCKQUOTES_Define($$)
- {
- my ($hash, $def) = @_;
- my @a = split("[ \t][ \t]*", $def);
- if (scalar(@a) != 2) {
- return "Invalid arguments! Define as 'define <name> STOCKQUOTES'";
- }
- $attr{$hash->{NAME}}{"pollInterval"} = 300;
- $attr{$hash->{NAME}}{"queryTimeout"} = 120;
- $attr{$hash->{NAME}}{"defaultSource"} = "europe";
- $attr{$hash->{NAME}}{"currency"} = "EUR";
-
- $hash->{QUOTER} = Finance::Quote->new;
- $hash->{QUOTER}->timeout(300); # Cancel fetch operation if it takes
- readingsSingleUpdate($hash, "state", "Initialized",1);
-
- STOCKQUOTES_UpdateCurrency($hash);
- STOCKQUOTES_QueueTimer($hash, 5);
-
- return undef;
- }
- sub STOCKQUOTES_Attr(@)
- {
- my ($cmd,$name,$aName,$aVal) = @_;
- my $hash = $defs{$name};
- if($aName eq "currency") {
- return STOCKQUOTES_UpdateCurrency($hash, $aVal);
- }
- elsif($aName eq "sources") {
- return STOCKQUOTES_ClearReadings($hash);
- }
-
- return undef;
- }
- sub STOCKQUOTES_UpdateCurrency($;$)
- {
- my ($hash, $cur) = @_;
- $cur = AttrVal($hash->{NAME}, "currency", "") if not defined $cur;
- Log3 $hash->{NAME}, 4, "STOCKQUOTES_UpdateCurrency to $cur";
- $hash->{QUOTER}->set_currency($cur);
-
- # delete all readings for the previous currency
- STOCKQUOTES_DeleteReadings($hash, undef);
-
- return undef;
- }
- sub STOCKQUOTES_Undefine($$)
- {
- my ($hash, $arg) = @_;
- RemoveInternalTimer($hash);
- BlockingKill($hash->{helper}{RUNNING_PID}) if(defined($hash->{helper}{RUNNING_PID}));
- return undef;
- }
- sub STOCKQUOTES_SetStockHashes($$)
- {
- my ($hash, $stocks) = @_;
-
- my $str = "";
- my $first = 1;
- foreach my $ex (keys %{ $stocks }) {
- $str .= "," unless $first;
- $first = 0;
- Log3 $hash->{NAME}, 4, "KEY: $ex";
-
- $str .= $ex . ":" . $stocks->{$ex}[0] . ":" . $stocks->{$ex}[1];
- }
-
- Log3 $hash->{NAME}, 5, "STOCKQUOTES_SetStockHashes: $str";
- $attr{$hash->{NAME}}{"stocks"} = $str;
-
- return undef;
- }
- sub STOCKQUOTES_GetStockHashes($)
- {
- my ($hash) = @_;
- my $name = $hash->{NAME};
- my @stocks = split ',', AttrVal($name, "stocks", "");
- my %stockHash = ();
- foreach my $stock (@stocks) {
- my @toks = split ":", $stock;
- $stockHash{$toks[0]} = [$toks[1], $toks[2]];
- }
- return \%stockHash;
- }
- sub STOCKQUOTES_ClearReadings($)
- {
- my ($hash, $stockName) = @_;
- delete $hash->{READINGS};
- return undef;
- }
- sub STOCKQUOTES_DeleteReadings($$)
- {
- my ($hash, $prefix) = @_;
- my $delStr = defined($prefix) ? ".*" . $prefix . "_.*" : ".*";
- fhem("deletereading $hash->{NAME} $delStr", 1);
- return undef;
- }
- sub STOCKQUOTES_RemoveStock($$)
- {
- my ($hash, $stockName) = @_;
- my $stocks = STOCKQUOTES_GetStockHashes($hash);
-
- if (not exists $stocks->{$stockName}) {
- return "There is no stock named '$stockName' to delete!";
- }
- Log3 $hash->{NAME}, 3, "STOCKQUOTES_RemoveStock: Removing $stockName";
- delete $stocks->{$stockName};
- if (not exists $stocks->{$stockName}) {
- Log3 $hash->{NAME}, 3, "DELETED";
- }
-
- STOCKQUOTES_SetStockHashes($hash, $stocks);
-
- STOCKQUOTES_DeleteReadings($hash, $stockName);
-
- return undef;
- }
- sub STOCKQUOTES_ChangeAmount($$$$)
- {
- my ($hash, $stockName, $amount, $price) = @_;
- my $stocks = STOCKQUOTES_GetStockHashes($hash);
-
- if (exists $stocks->{$stockName}) {
- $stocks->{$stockName}->[0] += $amount;
- $stocks->{$stockName}->[0] = 0 if ($stocks->{$stockName}[0] < 0);
- $stocks->{$stockName}->[1] += $price;
-
- if ($stocks->{$stockName}->[0] == 0)
- {
- Log3 $hash->{NAME}, 3, "STOCKQUOTES_ChangeAmount: Amount set to 0. Removing stock: $stockName";
- delete $stocks->{$stockName};
- STOCKQUOTES_DeleteReadings($hash, $stockName);
- }
- }
- else {
- $stocks->{$stockName}->[0] = $amount;
- $stocks->{$stockName}->[1] = $price;
- }
- STOCKQUOTES_SetStockHashes($hash, $stocks);
-
- STOCKQUOTES_QueueTimer($hash, 0);
-
- return undef;
- }
- sub STOCKQUOTES_Set($@)
- {
- my ($hash, $name, $cmd, @args) = @_;
- if($cmd eq "buy" or $cmd eq "sell") {
- if (scalar(@args) != 3) {
- return "Invalid arguments! Usage 'set $name $cmd <stockname> <count> <price total>";
- }
- my $stockName = $args[0];
- my $amount = $args[1];
- my $price = $args[2];
- my $fac = ($cmd eq "buy") ? 1 : -1;
- my $str = STOCKQUOTES_ChangeAmount($hash, $stockName, $fac * $amount, $fac * $price);
- STOCKQUOTES_QueueTimer($hash, 0);
- return $str;
- }
- elsif($cmd eq "add") {
- if (scalar(@args) != 1) {
- return "Invalid arguments! Usage 'set $name add <stockname>";
- }
- return STOCKQUOTES_ChangeAmount($hash, $args[0], 0 ,0);
- }
- elsif($cmd eq "remove") {
- if (scalar(@args) != 1) {
- return "Invalid arguments! Usage 'set $name remove <stockname>";
- }
- return STOCKQUOTES_RemoveStock($hash, $args[0]);
- }
- elsif($cmd eq "update") {
- return STOCKQUOTES_QueueTimer($hash, 0);
- }
- elsif($cmd eq "clearReadings") {
- return STOCKQUOTES_ClearReadings($hash);
- }
-
- my $res = "Unknown argument " . $cmd . ", choose one of " .
- "update buy sell add remove clearReadings";
- return $res ;
- }
- sub STOCKQUOTES_Get($@)
- {
- my ($hash, $name, $cmd, @args) = @_;
- if($cmd eq "sources") {
- if (scalar(@args) != 0) {
- return "Invalid arguments! Usage 'get $name $cmd'";
- }
- return "Available sources: " . join("\n", $hash->{QUOTER}->sources());
- }
- elsif($cmd eq "currency") {
- if (scalar(@args) != 1) {
- return "Invalid arguments! Usage 'get $name $cmd <case-sensitive search name>'";
- }
- my $currs = $hash->{QUOTER}->currency_lookup( name => $args[0] );
- return "Found currencies: " . join(",", keys %{ $currs });
- }
- my $res = "Unknown argument " . $cmd . ", choose one of " .
- "sources currency";
- return $res ;
- }
- sub STOCKQUOTES_QueueTimer($$)
- {
- my ($hash, $pollInt) = @_;
- Log3 $hash->{NAME}, 4, "STOCKQUOTES_QueueTimer: $pollInt seconds";
-
- RemoveInternalTimer($hash);
- delete($hash->{helper}{RUNNING_PID});
- InternalTimer(time() + $pollInt, "STOCKQUOTES_QueryQuotes", $hash, 0);
-
- return undef;
- }
- sub STOCKQUOTES_QueryQuotes($)
- {
- my ($hash) = @_;
- my $name = $hash->{NAME};
-
- if (not exists($hash->{helper}{RUNNING_PID})) {
- Log3 $hash->{NAME}, 4, 'STOCKQUOTES: Start blocking query';
- readingsSingleUpdate($hash, "state", "Updating",1);
- $hash->{helper}{RUNNING_PID} = BlockingCall("STOCKQUOTES_QueryQuotesBlocking",
- $hash,
- "STOCKQUOTES_QueryQuotesFinished",
- AttrVal($hash, "queryTimeout", 120),
- "STOCKQUOTES_QueryQuotesAbort",
- $hash);
- }
- else {
- Log3 $hash->{NAME}, 4, 'STOCKQUOTES_QueryQuotes: Blocking not started because still one running';
- }
-
- return undef;
- }
- # return the source that should be used for a stock
- sub STOCKQUOTES_GetSource($$)
- {
- my ($hash, $stock) = @_;
- my $name = $hash->{NAME};
- my @exs = split ",", AttrVal($name, "sources", "");
-
- my %exHash = ();
- foreach my $ex (@exs) {
- my @tok = split ":", $ex;
- $exHash{$tok[0]} = $tok[1];
- }
-
- if (exists($exHash{$stock})) {
- return $exHash{$stock};
- }
-
- return AttrVal($name, "defaultSource", "europe");
- }
- sub STOCKQUOTES_QueryQuotesBlocking($)
- {
- my ($hash) = @_;
- my $name = $hash->{NAME};
-
- Log3 $name, 4, 'STOCKQUOTES_QueryQuotesBlocking';
- my $stocks = STOCKQUOTES_GetStockHashes($hash);
-
- my %sources = ();
- foreach my $symbol (keys %{ $stocks }) {
- my @toks = split ':', $symbol;
- my $symbName = $toks[0];
-
- my $targetSource = STOCKQUOTES_GetSource($hash, $symbName);
- if (not exists $sources{$targetSource}) {
- $sources{$targetSource} = ();
- }
- push(@{$sources{$targetSource}}, $symbName);
- Log3 $name, 4, "STOCKQUOTES_QueryQuotesBlocking: Query stockname: $symbName from source $targetSource";
- }
-
- my $ret = $hash->{NAME};
- foreach my $srcKey (keys %sources) {
- Log3 $name, 4, "STOCKQUOTES_QueryQuotesBlocking: Fetching from source: $srcKey";
- my %quotes = $hash->{QUOTER}->fetch($srcKey, @{$sources{$srcKey}});
- foreach my $tag (keys %quotes) {
- my @keys = split($;, $tag);
-
- next if $quotes{$keys[0], 'success'} != 1;
-
- my $val = $quotes{$keys[0], $keys[1]};
- next if (not defined $val);
-
- $ret .= "|" . join("&", @keys) . "&";
- $val = encode('UTF-8', $val, Encode::FB_CROAK) if ($keys[1] eq "name");
- $ret .= $val;
- }
- }
-
- Log3 $name, 4, 'STOCKQUOTES_QueryQuotesBlocking Return value: ' . $ret;
-
- #$ret = "myC|A0M16S¤cy&EUR|A0M16S&last&125.94|A0M16S&errormsg&|A0M16S&symbol&LU0321021155|A0M16S&time&17:52|A0M16S&isodate&2015-02-16|A0M16S&name&VERMöGENSMANAGEMENT BALANCE A€|A0M16S&source&VWD|A0M16S&price&125.94|A0M16S&date&02/16/2015|A0M16S&success&1";
- return $ret;
- }
- sub STOCKQUOTES_QueryQuotesAbort($$$)
- {
- my ($hash) = @_;
- my $name = $hash->{NAME};
- Log3 $name, 3, 'STOCKQUOTES_QueryQuotesAbort: Blocking call aborted due to timeout!';
- readingsSingleUpdate($hash, "state", "Update aborted",1);
- delete($hash->{helper}{RUNNING_PID});
- STOCKQUOTES_QueueTimer($hash, AttrVal($name, "pollInterval", 300));
-
- return undef;
- }
- sub STOCKQUOTES_QueryQuotesFinished($)
- {
- my ($string) = @_;
-
- return unless(defined($string));
-
- my @a = split("\\|",$string);
- my $name = $a[0];
- my $hash = $defs{$name};
- Log3 $name, 4, 'STOCKQUOTES_QueryQuotesFinished';
- delete($hash->{helper}{RUNNING_PID});
- my $stocks = STOCKQUOTES_GetStockHashes($hash);
- my %stockState = ();
- readingsBeginUpdate($hash);
- for my $i (1 .. $#a)
- {
- my @toks = split '&',$a[$i];
-
- # HACK: replace "3.2%" with "3.2" since we dont want units
- chop $toks[2] if ($toks[1] eq "p_change" and $toks[2] =~ /%$/);
- readingsBulkUpdate($hash, $toks[0] . "_" . $toks[1], $toks[2]);
-
- # build a hash filled with current values
- $stockState{$toks[0]}{$toks[1]} = $toks[2];
- }
- readingsEndUpdate($hash, 1);
- # build depot status
- readingsBeginUpdate($hash);
- foreach my $i (keys %stockState) {
- # we assume that every stockname is also in our stocks-hash. Otherwise something went terribly wrong
- my $stockCount = $stocks->{$i}->[0];
- my $stockBuyPrice = $stocks->{$i}->[1];
- my $last = (exists $stockState{$i}{"last"}) ? $stockState{$i}{"last"} : undef;
- my $previous = (exists $stockState{$i}{"previous"}) ? $stockState{$i}{"previous"} : undef;
- my $stockValue = (defined $last) ? $stockCount * $last : undef;
- my $stockValuePrev = (defined $previous) ? $stockCount * $previous : undef;
-
- # statics
- readingsBulkUpdate($hash, $i . "_d_stockcount", $stockCount);
- readingsBulkUpdate($hash, $i . "_d_buy_value_total", $stockBuyPrice);
- readingsBulkUpdate($hash, $i . "_d_buy_quote", ($stockCount == 0) ? 0 : sprintf("%.2f", $stockBuyPrice / $stockCount));
- # end
-
- if (defined($stockValue))
- {
- readingsBulkUpdate($hash, $i . "_d_cur_value_total", sprintf("%.2f", $stockValue));
- readingsBulkUpdate($hash, $i . "_d_value_diff_total", sprintf("%.2f", $stockValue - $stockBuyPrice));
- readingsBulkUpdate($hash, $i . "_d_p_change_total", ($stockBuyPrice == 0) ? 0 : sprintf("%.2f", 100.0 * (($stockValue / $stockBuyPrice) - 1 )));
-
- my $valueDiff = (defined $previous and defined $last) ? $stockCount * ($last - $previous) : undef;
- readingsBulkUpdate($hash, $i . "_d_value_diff", sprintf("%.2f", $valueDiff)) if defined $valueDiff;
- }
- if (defined($stockValuePrev))
- {
- readingsBulkUpdate($hash, $i . "_d_prev_value_total", sprintf("%.2f", $stockValuePrev));
- }
- }
-
- # update depot data
- my %depotSummary = ();
- $depotSummary{"depot_cur_value_total"} = 0;
- $depotSummary{"depot_prev_value_total"} = 0;
- $depotSummary{"depot_value_diff"} = 0;
- $depotSummary{"depot_buy_value_total"} = 0;
- foreach my $i (keys %stockState) {
- $depotSummary{"depot_buy_value_total"} += ReadingsVal($name, $i . "_d_buy_value_total", 0);
- $depotSummary{"depot_cur_value_total"} += ReadingsVal($name, $i . "_d_cur_value_total", 0);
- $depotSummary{"depot_prev_value_total"} += ReadingsVal($name, $i . "_d_prev_value_total", 0);
- $depotSummary{"depot_value_diff"} += ReadingsVal($name, $i . "_d_value_diff", 0);
- }
- readingsBulkUpdate($hash, "depot_buy_value_total", $depotSummary{"depot_buy_value_total"});
- readingsBulkUpdate($hash, "depot_cur_value_total", $depotSummary{"depot_cur_value_total"});
- readingsBulkUpdate($hash, "depot_value_diff_total", sprintf("%.2f", $depotSummary{"depot_cur_value_total"} - $depotSummary{"depot_buy_value_total"}));
- readingsBulkUpdate($hash, "depot_value_diff", sprintf("%.2f", $depotSummary{"depot_value_diff"}));
-
- my $depot_p_change = 0.0;
- if ($depotSummary{"depot_prev_value_total"} > 0.0) {
- $depot_p_change = sprintf("%.2f", 100.0 * (($depotSummary{"depot_cur_value_total"} / $depotSummary{"depot_prev_value_total"}) - 1 ));
- }
- readingsBulkUpdate($hash, "depot_p_change", $depot_p_change);
- my $depot_p_change_total = 0.0;
- if ($depotSummary{"depot_buy_value_total"} > 0.0) {
- $depot_p_change_total = sprintf("%.2f", 100.0 * (($depotSummary{"depot_cur_value_total"} / $depotSummary{"depot_buy_value_total"}) - 1 ));
- }
- readingsBulkUpdate($hash, "depot_p_change_total", $depot_p_change_total);
-
- my $now = gettimeofday();
- my $fmtDateTime = FmtDateTime($now);
- readingsBulkUpdate($hash, "state", $fmtDateTime);
- readingsEndUpdate($hash, 1);
- STOCKQUOTES_QueueTimer($hash, AttrVal($name, "pollInterval", 300));
-
- return undef;
- }
- 1;
- =pod
- =item device
- =item summary fetches stock quotes from data sources
- =item summary_DE Kursdaten von Wertpapieren
- =begin html
- <a name="STOCKQUOTES"></a>
- <h3>STOCKQUOTES</h3>
- (en | <a href="commandref_DE.html#STOCKQUOTES">de</a>)
- <ul>
- <a name="STOCKQUOTES"></a>
- Fetching actual stock quotes from various sources<br>
- <b>Preliminary</b><br>
- Perl module Finance::Quote must be installed:<br>
- <code>cpan install Finance::Quote</code> or <code>sudo apt-get install libfinance-quote-perl</code><br><br>
-
- <b>Define</b>
- <ul>
- <code>define Depot STOCKQUOTES</code><br><br>
- </ul>
- <a name="STOCKQUOTESset"></a>
- <b>Set</b>
- <ul>
- <Symbol> depends on source. May also an WKN.<br><br>
- <li><code>set <name> buy <Symbol> <Amount> <Value of amount></code><br>
- Add a stock exchange security. If stock exchange security already exists, new values will be added to old values.<br><br>
- </li>
- <li><code>set <name> sell <Symbol> <Amount> <Value of amount></code><br>
- Remove a stock exchange security (or an part of it).<br><br>
- </li>
- <li><code>set <name> add <Symbol></code><br>
- Watch only<br><br>
- </li>
- <li><code>set <name> remove <Symbol></code><br>
- Remove watched stock exchange security.<br><br>
- </li>
- <li><code>set <name> clearReadings</code><br>
- Clears all readings.<br><br>
- </li>
- <li><code>set <name> update</code><br>
- Refresh all readings.<br><br>
- </li>
- </ul>
-
- <a name="STOCKQUOTESget"></a>
- <b>Get</b>
- <ul>
- <li><code>get <name> sources</code><br>
- Lists all avaiable data sources.<br><br>
- </li>
- <li><code>get <name> currency <Symbol></code><br>
- Get currency of stock exchange securities<br><br>
- </li>
- </ul>
- <a name="STOCKQUOTESattr"></a>
- <b>Attributes</b>
- <ul>
- <li>currency<br>
- All stock exchange securities will shown in this currency.<br>
- Default: EUR<br><br>
- </li>
- <li>defaultSource<br>
- Default source for stock exchange securities values.<br>
- Default: europe, valid values: from <code>get <name> sources</code><br><br>
- </li>
- <li>queryTimeout<br>
- Fetching timeout in seconds.<br>
- Standard: 120, valid values: Number<br><br>
- </li>
- <li>pollInterval<br>
- Refresh interval in seconds.<br>
- Standard: 300, valid values: Number<br><br>
- </li>
- <li>sources<br>
- An individual data source can be set for every single stock exchange securities.<br>
- Data sources can be fetched with: <code>get <name> sources</code>.<br>
- Format: <Symbol>:<Source>[,<Symbol>:<Source>...]<br>
- Example: <code>A0M16S:vwd,532669:unionfunds,849104:unionfunds</code><br>
- Stock exchange securities not listed in sources will be updated from defaultSource.<br><br>
- </li>
- <li>stocks<br>
- Will be created/modified via buy/sell/add/remove<br>
- Contains stock exchange securities informations in format: <Symbol>:<Anzahl>:<Einstandswert>[,<Symbol>:<Anzahl>:<Einstandswert>...]<br><br>
- </li>
- </ul><br>
- </ul>
- =end html
- =begin html_DE
- <a name="STOCKQUOTES"></a>
- <h3>STOCKQUOTES</h3>
- (<a href="commandref.html#STOCKQUOTES">en</a> | de)
- <ul>
- <a name="STOCKQUOTES"></a>
- Wertpapierdaten von verschiedenen Quellen holen<br>
- <b>Vorbereitung</b><br>
- Perl Modul Finance::Quote muss installiert werden:<br>
- <code>cpan install Finance::Quote</code> oder <code>sudo apt-get install libfinance-quote-perl</code><br><br>
-
- <b>Define</b>
- <ul>
- <code>define <name> STOCKQUOTES</code><br><br>
- </ul>
- <a name="STOCKQUOTESset"></a>
- <b>Set</b>
- <ul>
- <Symbol> hängt von den jeweiligen Quellen ab. Kann auch eine WKN sein. Hier muss ggf. experimentiert werden.<br><br>
- <li><code>set <name> buy <Symbol> <Menge> <Gesamtpreis></code><br>
- Wertpapier in Depot einbuchen. Wenn dieses Wertpapier bereits vorhanden ist, werden die Neuen einfach dazuaddiert.<br><br>
- </li>
- <li><code>set <name> sell <Symbol> <Menge> <Gesamtpreis></code><br>
- Wertpapier (auch Teilmenge) wieder ausbuchen.<br><br>
- </li>
- <li><code>set <name> add <Symbol></code><br>
- Wertpapier nur beobachten<br><br>
- </li>
- <li><code>set <name> remove <Symbol></code><br>
- Entferne Wertpapier das nur beobachtet wird.<br><br>
- </li>
- <li><code>set <name> clearReadings</code><br>
- Alle Readings löschen.<br><br>
- </li>
- <li><code>set <name> update</code><br>
- Alle Readings aktualisieren.<br><br>
- </li>
- </ul>
-
- <a name="STOCKQUOTESget"></a>
- <b>Get</b>
- <ul>
- <li><code>get <name> sources</code><br>
- Verfügbare Datenquellen auflisten. Diese werden für die Attribute defaultSource und sources benötigt<br><br>
- </li>
- <li><code>get <name> currency <Symbol></code><br>
- Wertpapierwährung ermitteln<br><br>
- </li>
- </ul>
- <a name="STOCKQUOTESattr"></a>
- <b>Attribute</b>
- <ul>
- <li>currency<br>
- Währung, in der die Wertpapiere angezeigt werden.<br>
- Default: EUR, gültige Werte: Währungskürzel<br><br>
- </li>
- <li>defaultSource<br>
- Standardquelle für die Wertpapierdaten.<br>
- Default: europe, gültige Werte: alles was <code>get <name> sources</code> ausgibt.<br><br>
- </li>
- <li>queryTimeout<br>
- Timeout beim holen der Daten in Sekunden.<br>
- Standard: 120, gültige Werte: Zahl<br><br>
- </li>
- <li>pollInterval<br>
- Aktualisierungsintervall in Sekunden.<br>
- Standard: 300, gültige Werte: Zahl<br><br>
- </li>
- <li>sources<br>
- Für jedes Wertpapier kann eine eigene Datenquelle definiert werden.<br>
- Die Datenquellen können über <code>get <name> sources</code> angefragt werden.<br>
- Format: <Symbol>:<Source>[,<Symbol>:<Source>...]<br>
- Beispiel: <code>A0M16S:vwd,532669:unionfunds,849104:unionfunds</code><br>
- Alle nicht aufgeführten Werpapiere werden über die defaultSource abgefragt.<br><br>
- </li>
- <li>stocks<br>
- Wird über buy/sell/add/remove angelegt/modifiziert<br>
- Enthält die Werpapiere im Format <Symbol>:<Anzahl>:<Einstandswert>[,<Symbol>:<Anzahl>:<Einstandswert>...]<br><br>
- </li>
- </ul><br>
- </ul>
- =end html_DE
- =cut
|