73_WaterCalculator.pm 83 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912
  1. # $Id: 73_WaterCalculator.pm 16603 2018-04-13 17:58:42Z Sailor $
  2. ########################################################################################################################
  3. #
  4. # 73_WaterCalculator.pm
  5. # Observes a reading of a device which represents the actual counter (e.g. OW_devive)
  6. # acting as Water counter, calculates the corresponding values and writes them back to
  7. # the counter device.
  8. # Written and best viewed with Notepad++ v.6.8.6; Language Markup: Perl
  9. # This is based on "ElectricityCalulator" from Matthias Deeke. All rights to him.
  10. #
  11. # Author : Matthias Deeke; Jürgen Brugger
  12. # e-mail : matthias.deeke(AT)deeke(DOT)eu; juergen.brugger(AT)gmail(DOT)com
  13. # Fhem Forum : https://forum.fhem.de/index.php?topic=58579.0;topicseen
  14. # Fhem Wiki : Not yet implemented
  15. #
  16. # This file is part of fhem.
  17. #
  18. # Fhem is free software: you can redistribute it and/or modify
  19. # it under the terms of the GNU General Public License as published by
  20. # the Free Software Foundation, either version 2 of the License, or
  21. # (at your option) any later version.
  22. #
  23. # Fhem is distributed in the hope that it will be useful,
  24. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. # GNU General Public License for more details.
  27. #
  28. # You should have received a copy of the GNU General Public License
  29. # along with fhem. If not, see <http://www.gnu.org/licenses/>.
  30. #
  31. # fhem.cfg: define <devicename> WaterCalculator <regexp>
  32. #
  33. # Example 1:
  34. # define myWaterCalculator WaterCalculator myWaterCounter:CounterA.*
  35. #
  36. ########################################################################################################################
  37. ########################################################################################################################
  38. # List of open Problems / Issues:
  39. #
  40. # - EXPERIMENTAL VERSION ONLY!
  41. #
  42. ########################################################################################################################
  43. package main;
  44. use strict;
  45. use warnings;
  46. ###START###### Initialize module ##############################################################################START####
  47. sub WaterCalculator_Initialize($)
  48. {
  49. my ($hash) = @_;
  50. $hash->{STATE} = "Init";
  51. $hash->{DefFn} = "WaterCalculator_Define";
  52. $hash->{UndefFn} = "WaterCalculator_Undefine";
  53. $hash->{GetFn} = "WaterCalculator_Get";
  54. $hash->{SetFn} = "WaterCalculator_Set";
  55. $hash->{AttrFn} = "WaterCalculator_Attr";
  56. $hash->{NotifyFn} = "WaterCalculator_Notify";
  57. $hash->{DbLog_splitFn} = "WaterCalculator_DbLog_splitFn";
  58. $hash->{NotifyOrderPrefix} = "10-"; # Want to be called before the rest
  59. $hash->{AttrList} = "disable:0,1 " .
  60. "header " .
  61. "WaterCounterOffset " .
  62. "WaterCubicPerCounts " .
  63. "BasicPricePerAnnum " .
  64. "WaterPricePerCubic " .
  65. "MonthlyPayment " .
  66. "MonthOfAnnualReading " .
  67. "ReadingDestination:CalculatorDevice,CounterDevice " .
  68. "WFRUnit:l/min,m&sup3;/min,m&sup3;/h " .
  69. "Currency:&#8364;,&#163;,&#36; " .
  70. $readingFnAttributes;
  71. }
  72. ####END####### Initialize module ###############################################################################END#####
  73. ###START###### Activate module after module has been used via fhem command "define" ##########################START####
  74. sub WaterCalculator_Define($$$)
  75. {
  76. my ($hash, $def) = @_;
  77. my ($name, $type, $RegEx, $RegExst) = split("[ \t]+", $def, 4);
  78. ### Check whether regular expression has correct syntax
  79. if(!$RegEx || $RegExst)
  80. {
  81. my $msg = "Wrong syntax: define <name> WaterCalculator device[:event]";
  82. return $msg;
  83. }
  84. ### Check whether regular expression is misleading
  85. eval { "Hallo" =~ m/^$RegEx$/ };
  86. return "Bad regexp: $@" if($@);
  87. $hash->{REGEXP} = $RegEx;
  88. ### Writing values to global hash
  89. notifyRegexpChanged($hash, $RegEx);
  90. $hash->{NAME} = $name;
  91. $hash->{STATE} = "active";
  92. $hash->{REGEXP} = $RegEx;
  93. if(defined($attr{$hash}{WFRUnit}))
  94. {
  95. if ($attr{$hash}{WFRUnit} eq "l/min" ) {$hash->{system}{WFRUnitFactor} = 1 ;}
  96. elsif ($attr{$hash}{WFRUnit} eq "m&sup3;/min") {$hash->{system}{WFRUnitFactor} = 0.001 ;}
  97. elsif ($attr{$hash}{WFRUnit} eq "m&sup3;/h") {$hash->{system}{WFRUnitFactor} = 0.06 ;}
  98. else {$hash->{system}{WFRUnitFactor} = 1 ;}
  99. }
  100. else
  101. {
  102. $hash->{system}{WFRUnitFactor} = 1;
  103. }
  104. ### Writing log entry
  105. Log3 $name, 5, $name. " : WaterCalculator - Starting to define module";
  106. return undef;
  107. }
  108. ####END####### Activate module after module has been used via fhem command "define" ############################END#####
  109. ###START###### Deactivate module module after "undefine" command by fhem ######################################START####
  110. sub WaterCalculator_Undefine($$)
  111. {
  112. my ($hash, $def) = @_;
  113. my $name = $hash->{NAME};
  114. Log3 $name, 3, $name. " WaterCalculator- The Water calculator has been undefined. Values corresponding to water meter will no longer calculated";
  115. return undef;
  116. }
  117. ####END####### Deactivate module module after "undefine" command by fhem #######################################END#####
  118. ###START###### Handle attributes after changes via fhem GUI ###################################################START####
  119. sub WaterCalculator_Attr(@)
  120. {
  121. my @a = @_;
  122. my $name = $a[1];
  123. my $hash = $defs{$name};
  124. ### Check whether "disable" attribute has been provided
  125. if ($a[2] eq "disable")
  126. {
  127. if ($a[3] eq 0)
  128. {
  129. $hash->{STATE} = "active";
  130. }
  131. elsif ($a[3] eq 1)
  132. {
  133. $hash->{STATE} = "disabled";
  134. }
  135. }
  136. ### Check whether "WFRUnit" attribute has been provided
  137. if ($a[2] eq "WFRUnit")
  138. {
  139. if ($a[3] eq "l/min" ) {$hash->{system}{WFRUnitFactor} = 1 ;}
  140. elsif ($a[3] eq "m&sup3;/min") {$hash->{system}{WFRUnitFactor} = 0.001 ;}
  141. elsif ($a[3] eq "m&sup3;/h") {$hash->{system}{WFRUnitFactor} = 0.06 ;}
  142. else {$hash->{system}{WFRUnitFactor} = 1 ;}
  143. }
  144. return undef;
  145. }
  146. ####END####### Handle attributes after changes via fhem GUI ####################################################END#####
  147. ###START###### Provide units for DbLog database via DbLog_splitFn #############################################START####
  148. sub WaterCalculator_DbLog_splitFn($$)
  149. {
  150. my ($event, $name) = @_;
  151. my ($reading, $value, $unit);
  152. my $hash = $defs{$name};
  153. my @argument = split("[ \t][ \t]*", $event);
  154. ### Delete ":" and everything behind in readings name
  155. $argument[0] =~ s/:.*//;
  156. ### Log entries for debugging
  157. Log3 $name, 5, $name. " : WaterCalculator_DbLog_splitFn - Content of event : " . $event;
  158. Log3 $name, 5, $name. " : WaterCalculator_splitFn - Content of argument[0] : " . $argument[0];
  159. Log3 $name, 5, $name. " : WaterCalculator_splitFn - Content of argument[1] : " . $argument[1];
  160. ### If the reading contains "_ConsumptionCost" or "_FinanceReserve"
  161. if (($argument[0] =~ /_ConsumptionCost/) || ($argument[0] =~ /_FinanceReserve/))
  162. {
  163. ### Log entries for debugging
  164. Log3 $name, 5, $name. " : WaterCalculator_DbLog_splitFn - ConsumptionCost-Reading detected : " . $argument[0];
  165. ### Get values being changed from hash
  166. $reading = $argument[0];
  167. $value = $argument[1];
  168. $unit = $attr{$hash}{Currency};
  169. }
  170. ### If the reading contains "_Flow"
  171. elsif ($argument[0] =~ /_Flow/)
  172. {
  173. ### Log entries for debugging
  174. Log3 $name, 5, $name. " : WaterCalculator_DbLog_splitFn - Flow-Reading detected : " . $argument[0];
  175. ### Get values being changed from hash
  176. $reading = $argument[0];
  177. $value = $argument[1];
  178. $unit = $attr{$hash}{WFRUnit};
  179. }
  180. ### If the reading contains "_Counter" or "_Last" or ("_Consumption" but not "_ConsumptionCost") or "_PrevRead"
  181. elsif (($argument[0] =~ /_Counter/) || ($argument[0] =~ /_Last/) || (($argument[0] =~ /_Consumption/) && ($argument[0] !~ /_ConsumptionCost/)) || ($argument[0] =~ /_PrevRead/))
  182. {
  183. ### Log entries for debugging
  184. Log3 $name, 5, $name. " : WaterCalculator_DbLog_splitFn - Counter/Consumption-Reading detected: " . $argument[0];
  185. ### Get values being changed from hash
  186. $reading = $argument[0];
  187. $value = $argument[1];
  188. $unit = "m&sup3;";
  189. }
  190. ### If the reading is unknown
  191. else
  192. {
  193. ### Log entries for debugging
  194. Log3 $name, 5, $name. " : WaterCalculator_DbLog_splitFn - unspecified-Reading detected : " . $argument[0];
  195. ### Get values being changed from hash
  196. $reading = $argument[0];
  197. $value = $argument[1];
  198. $unit = "";
  199. }
  200. return ($reading, $value, $unit);
  201. }
  202. ####END####### Provide units for DbLog database via DbLog_splitFn ##############################################END#####
  203. ###START###### Manipulate reading after "get" command by fhem #################################################START####
  204. sub WaterCalculator_Get($@)
  205. {
  206. my ( $hash, @a ) = @_;
  207. ### If not enough arguments have been provided
  208. if ( @a < 2 )
  209. {
  210. return "\"get WaterCalculator\" needs at least one argument";
  211. }
  212. my $WaterCalcName = shift @a;
  213. my $reading = shift @a;
  214. my $value;
  215. my $ReturnMessage;
  216. if(!defined($hash->{helper}{gets}{$reading}))
  217. {
  218. my @cList = keys %{$hash->{helper}{gets}};
  219. return "Unknown argument $reading, choose one of " . join(" ", @cList);
  220. ### Create Log entries for debugging
  221. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - get list: " . join(" ", @cList);
  222. }
  223. if ( $reading ne "?")
  224. {
  225. ### Write current value
  226. $value = ReadingsVal($WaterCalcName, $reading, undef);
  227. ### Create Log entries for debugging
  228. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - get " . $reading . " with value: " . $value;
  229. ### Create ReturnMessage
  230. $ReturnMessage = $value;
  231. }
  232. return($ReturnMessage);
  233. }
  234. ####END####### Manipulate reading after "get" command by fhem ##################################################END#####
  235. ###START###### Manipulate reading after "set" command by fhem #################################################START####
  236. sub WaterCalculator_Set($@)
  237. {
  238. my ( $hash, @a ) = @_;
  239. ### If not enough arguments have been provided
  240. if ( @a < 2 )
  241. {
  242. return "\"set WaterCalculator\" needs at least one argument";
  243. }
  244. my $WaterCalcName = shift @a;
  245. my $reading = shift @a;
  246. my $value = join(" ", @a);
  247. my $ReturnMessage;
  248. if(!defined($hash->{helper}{gets}{$reading}))
  249. {
  250. my @cList = keys %{$hash->{helper}{sets}};
  251. return "Unknown argument $reading, choose one of " . join(" ", @cList);
  252. ### Create Log entries for debugging
  253. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - set list: " . join(" ", @cList);
  254. }
  255. if ( $reading ne "?")
  256. {
  257. ### Create Log entries for debugging
  258. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - set " . $reading . " with value: " . $value;
  259. ### Write current value
  260. readingsSingleUpdate($hash, $reading, $value, 1);
  261. ### Create ReturnMessage
  262. $ReturnMessage = $WaterCalcName . " - Successfully set " . $reading . " with value: " . $value;
  263. }
  264. return($ReturnMessage);
  265. }
  266. ####END####### Manipulate reading after "set" command by fhem ##################################################END#####
  267. ###START###### Calculate water meter values on changed events ###################################################START####
  268. sub WaterCalculator_Notify($$)
  269. {
  270. ### Define variables
  271. my ($WaterCalcDev, $WaterCountDev) = @_;
  272. my $WaterCalcName = $WaterCalcDev->{NAME};
  273. my $WaterCountName = $WaterCountDev->{NAME};
  274. my $WaterCountNameEvents = deviceEvents($WaterCountDev, 1);
  275. my $NumberOfChangedEvents = int(@{$WaterCountNameEvents});
  276. my $RegEx = $WaterCalcDev->{REGEXP};
  277. ### Check whether the Water calculator has been disabled
  278. if(IsDisabled($WaterCalcName))
  279. {
  280. return "";
  281. }
  282. ### Check whether all required attributes has been provided and if not, create them with standard values
  283. if(!defined($attr{$WaterCalcName}{BasicPricePerAnnum}))
  284. {
  285. ### Set attribute with standard value since it is not available
  286. $attr{$WaterCalcName}{BasicPricePerAnnum} = 0;
  287. ### Writing log entry
  288. Log3 $WaterCalcName, 3, $WaterCalcName. " : WaterCalculator - The attribute BasicPricePerAnnum was missing and has been set to 0";
  289. }
  290. if(!defined($attr{$WaterCalcName}{WaterCounterOffset}))
  291. {
  292. ### Set attribute with standard value since it is not available
  293. $attr{$WaterCalcName}{WaterCounterOffset} = 0;
  294. ### Writing log entry
  295. Log3 $WaterCalcName, 3, $WaterCalcName. " : WaterCalculator - The attribute WaterCounterOffset was missing and has been set to 0";
  296. }
  297. if(!defined($attr{$WaterCalcName}{WaterCubicPerCounts}))
  298. {
  299. ### Set attribute with standard value since it is not available
  300. $attr{$WaterCalcName}{WaterCubicPerCounts} = 1;
  301. ### Writing log entry
  302. Log3 $WaterCalcName, 3, $WaterCalcName. " : WaterCalculator - The attribute WaterCubicPerCounts was missing and has been set to 1 counts/qm";
  303. }
  304. if(!defined($attr{$WaterCalcName}{WaterPricePerCubic}))
  305. {
  306. ### Set attribute with standard value since it is not available
  307. $attr{$WaterCalcName}{WaterPricePerCubic} = 2.00;
  308. ### Writing log entry
  309. Log3 $WaterCalcName, 3, $WaterCalcName. " : WaterCalculator - The attribute WaterPricePerCubic was missing and has been set to 2.00 currency-unit/water Consumption-unit";
  310. }
  311. if(!defined($attr{$WaterCalcName}{MonthlyPayment}))
  312. {
  313. ### Set attribute with standard value since it is not available
  314. $attr{$WaterCalcName}{MonthlyPayment} = 0;
  315. ### Writing log entry
  316. Log3 $WaterCalcName, 3, $WaterCalcName. " : WaterCalculator - The attribute MonthlyPayment was missing and has been set to 0 currency-units";
  317. }
  318. if(!defined($attr{$WaterCalcName}{MonthOfAnnualReading}))
  319. {
  320. ### Set attribute with standard value since it is not available
  321. $attr{$WaterCalcName}{MonthOfAnnualReading} = 5;
  322. ### Writing log entry
  323. Log3 $WaterCalcName, 3, $WaterCalcName. " : WaterCalculator - The attribute MonthOfAnnualReading was missing and has been set to 5 which is the month May";
  324. }
  325. if(!defined($attr{$WaterCalcName}{Currency}))
  326. {
  327. ### Set attribute with standard value since it is not available
  328. $attr{$WaterCalcName}{Currency} = "&#8364;";
  329. ### Writing log entry
  330. Log3 $WaterCalcName, 3, $WaterCalcName. " : WaterCalculator - The attribute Currency was missing and has been set to &#8364;";
  331. }
  332. if(!defined($attr{$WaterCalcName}{WFRUnit}))
  333. {
  334. ### Set attribute with standard value since it is not available
  335. $attr{$WaterCalcName}{WFRUnit} = "l/min";
  336. $WaterCalcDev->{system}{WFRUnitFactor} = 1;
  337. ### Writing log entry
  338. Log3 $WaterCalcName, 3, $WaterCalcName. " : WaterCalculator - The attribute WFRUnit was missing and has been set to l_min";
  339. }
  340. if(!defined($attr{$WaterCalcName}{ReadingDestination}))
  341. {
  342. ### Set attribute with standard value since it is not available
  343. $attr{$WaterCalcName}{ReadingDestination} = "CalculatorDevice";
  344. ### Writing log entry
  345. Log3 $WaterCalcName, 3, $WaterCalcName. " : WaterCalculator - The attribute ReadingDestination was missing and has been set to CalculatorDevice";
  346. }
  347. if(!defined($attr{$WaterCalcName}{room}))
  348. {
  349. if(defined($attr{$WaterCountName}{room}))
  350. {
  351. ### Set attribute with standard value since it is not available
  352. $attr{$WaterCalcName}{room} = $attr{$WaterCountName}{room};
  353. ### Writing log entry
  354. Log3 $WaterCalcName, 3, $WaterCalcName. " : WaterCalculator - The attribute room was missing and has been set to the same room of the water meter: " . $attr{$WaterCountName}{room};
  355. }
  356. else
  357. {
  358. ### Set attribute with standard value since it is not available
  359. $attr{$WaterCalcName}{room} = "Water Consumption Counter";
  360. ### Writing log entry
  361. Log3 $WaterCalcName, 3, $WaterCalcName. " : WaterCalculator - The attribute room was missing and has been set to Water Consumption Counter";
  362. }
  363. }
  364. ### For each feedback on in the array of defined regexpression which has been changed
  365. for (my $i = 0; $i < $NumberOfChangedEvents; $i++)
  366. {
  367. ### Extract event
  368. my $s = $WaterCountNameEvents->[$i];
  369. ### Filtering all events which do not match the defined regex
  370. if(!defined($s))
  371. {
  372. next;
  373. }
  374. my ($WaterCountReadingName, $WaterCountReadingValueCurrent) = split(": ", $s, 2); # resets $1
  375. if("$WaterCountName:$s" !~ m/^$RegEx$/)
  376. {
  377. next;
  378. }
  379. ### Extracting value
  380. if(defined($1))
  381. {
  382. my $RegExArg = $1;
  383. if(defined($2))
  384. {
  385. $WaterCountReadingName = $1;
  386. $RegExArg = $2;
  387. }
  388. $WaterCountReadingValueCurrent = $RegExArg if(defined($RegExArg) && $RegExArg =~ m/^(-?\d+\.?\d*)/);
  389. }
  390. if(!defined($WaterCountReadingValueCurrent) || $WaterCountReadingValueCurrent !~ m/^(-?\d+\.?\d*)/)
  391. {
  392. next;
  393. }
  394. ###Get current Counter and transform in water consumption (qm) as read on mechanic water meter
  395. $WaterCountReadingValueCurrent = $1 * $attr{$WaterCalcName}{WaterCubicPerCounts} + $attr{$WaterCalcName}{WaterCounterOffset};
  396. my $WaterCountReadingTimestampCurrent = ReadingsTimestamp($WaterCountName,$WaterCountReadingName,0);
  397. ### Create Log entries for debugging
  398. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator Begin_______________________________________________________________________________________________________________________________";
  399. ### Create name and destination device for general reading prefix
  400. my $WaterCalcReadingPrefix;
  401. my $WaterCalcReadingDestinationDevice;
  402. my $WaterCalcReadingDestinationDeviceName;
  403. if ($attr{$WaterCalcName}{ReadingDestination} eq "CalculatorDevice")
  404. {
  405. $WaterCalcReadingPrefix = ($WaterCountName . "_" . $WaterCountReadingName);
  406. $WaterCalcReadingDestinationDevice = $WaterCalcDev;
  407. $WaterCalcReadingDestinationDeviceName = $WaterCalcName;
  408. ### Create Log entries for debugging
  409. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - Attribut ReadingDestination has been set to CalculatorDevice";
  410. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCalcReadingPrefix : " . $WaterCalcReadingPrefix;
  411. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCalcReadingDestinationDevice : " . $WaterCalcReadingDestinationDevice;
  412. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCalcReadingDestinationDeviceName : " . $WaterCalcReadingDestinationDeviceName;
  413. }
  414. elsif ($attr{$WaterCalcName}{ReadingDestination} eq "CounterDevice")
  415. {
  416. $WaterCalcReadingPrefix = $WaterCountReadingName;
  417. $WaterCalcReadingDestinationDevice = $WaterCountDev;
  418. $WaterCalcReadingDestinationDeviceName = $WaterCountName;
  419. ### Create Log entries for debugging
  420. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - Attribut ReadingDestination has been set to CounterDevice";
  421. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCalcReadingPrefix : " . $WaterCalcReadingPrefix;
  422. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCalcReadingDestinationDevice : " . $WaterCalcReadingDestinationDevice;
  423. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCalcReadingDestinationDeviceName : " . $WaterCalcReadingDestinationDeviceName;
  424. }
  425. else
  426. {
  427. ### Create Log entries for debugging
  428. Log3 $WaterCalcName, 3, $WaterCalcName. " : WaterCalculator - Attribut ReadingDestination has not been set up correctly. Skipping event.";
  429. ### Skipping event
  430. next;
  431. }
  432. ### Restore previous Counter and if not available define it with "undef"
  433. my $WaterCountReadingTimestampPrevious = ReadingsTimestamp($WaterCalcReadingDestinationDeviceName, "." . $WaterCalcReadingPrefix . "_PrevRead", undef);
  434. my $WaterCountReadingValuePrevious = ReadingsVal($WaterCalcReadingDestinationDeviceName, "." . $WaterCalcReadingPrefix . "_PrevRead", undef);
  435. ### Create Log entries for debugging
  436. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCountReadingValuePrevious : " . $WaterCountReadingValuePrevious;
  437. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCalcReadingPrefix_PrevRead : " . $WaterCalcReadingPrefix . "_PrevRead";
  438. ### Find out whether there has been a previous value being stored
  439. if(defined($WaterCountReadingValuePrevious))
  440. {
  441. ### Write current water Consumption as previous water Consumption for future use in the WaterCalc-Device
  442. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, "." . $WaterCalcReadingPrefix. "_PrevRead", sprintf('%.3f', ($WaterCountReadingValueCurrent)),1);
  443. ### Create Log entries for debugging
  444. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - Previous value found. Continuing with calculations";
  445. }
  446. ### If not: save value and quit loop
  447. else
  448. {
  449. ### Write current water Consumption as previous Value for future use in the WaterCalc-Device
  450. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, "." . $WaterCalcReadingPrefix. "_PrevRead", sprintf('%.3f', ($WaterCountReadingValueCurrent)),1);
  451. ### Create Log entries for debugging
  452. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - Previous value NOT found. Skipping Loop";
  453. ### Jump out of loop since there is nothing to do anymore than to wait for the next value
  454. next;
  455. }
  456. ###### Find out whether the device has been freshly defined and certain readings have never been set up yet or certain readings have been deleted
  457. ### Find out whether the reading for the daily start value has not been written yet
  458. if(!defined(ReadingsVal($WaterCalcReadingDestinationDeviceName, $WaterCalcReadingPrefix . "_CounterDay1st", undef)))
  459. {
  460. ### Save current water Consumption as first reading of day = first after midnight and reset min, max value, value counter and value sum
  461. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_CounterDay1st", $WaterCountReadingValueCurrent, 1);
  462. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_CounterDayLast", $WaterCountReadingValuePrevious, 1);
  463. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, "." . $WaterCalcReadingPrefix . "_WFRDaySum", 0, 1);
  464. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, "." . $WaterCalcReadingPrefix . "_WFRDayCount", 0, 1);
  465. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_WFRDayMin", 0, 1);
  466. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_WFRDayMax", 0, 1);
  467. ### Create Log entries for debugging
  468. Log3 $WaterCalcName, 3, $WaterCalcName. " : WaterCalculator - Reading for the first daily value was not available and therfore reading and statistics have been written";
  469. }
  470. ### Find out whether the reading for the monthly start value has not been written yet
  471. if(!defined(ReadingsVal($WaterCalcReadingDestinationDeviceName, $WaterCalcReadingPrefix . "_CounterMonth1st", undef)))
  472. {
  473. ### Save current water Consumption as first reading of month
  474. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_CounterMonth1st", $WaterCountReadingValueCurrent, 1);
  475. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_CounterMonthLast", $WaterCountReadingValuePrevious, 1);
  476. ### Create Log entries for debugging
  477. Log3 $WaterCalcName, 3, $WaterCalcName. " : WaterCalculator - Reading for the first monthly value was not available and therfore reading has been written";
  478. }
  479. ### Find out whether the reading for the meter reading year value has not been written yet
  480. if(!defined(ReadingsVal($WaterCalcReadingDestinationDeviceName, $WaterCalcReadingPrefix . "_CounterMeter1st", undef)))
  481. {
  482. ### Save current water Consumption as first reading of month where Water-meter is read
  483. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_CounterMeter1st", $WaterCountReadingValueCurrent, 1);
  484. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_CounterMeterLast", $WaterCountReadingValuePrevious, 1);
  485. ### Create Log entries for debugging
  486. Log3 $WaterCalcName, 3, $WaterCalcName. " : WaterCalculator - Reading for the first value of water meter year was not available and therfore reading has been written";
  487. }
  488. ### Find out whether the reading for the yearly value has not been written yet
  489. if(!defined(ReadingsVal($WaterCalcReadingDestinationDeviceName, $WaterCalcReadingPrefix . "_CounterYear1st", undef)))
  490. {
  491. ### Save current water Consumption as first reading of the calendar year
  492. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_CounterYear1st", $WaterCountReadingValueCurrent, 1);
  493. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_CounterYearLast", $WaterCountReadingValuePrevious, 1);
  494. ### Create Log entries for debugging
  495. Log3 $WaterCalcName, 3, $WaterCalcName. " : WaterCalculator - Reading for the first yearly value was not available and therfore reading has been written";
  496. }
  497. ### Extracting year, month and day as numbers
  498. my $WaterCountReadingTimestampPreviousRelative = time_str2num($WaterCountReadingTimestampPrevious);
  499. my($WaterCountReadingTimestampPreviousSec,$WaterCountReadingTimestampPreviousMin,$WaterCountReadingTimestampPreviousHour,$WaterCountReadingTimestampPreviousMday,$WaterCountReadingTimestampPreviousMon,$WaterCountReadingTimestampPreviousYear,$WaterCountReadingTimestampPreviousWday,$WaterCountReadingTimestampPreviousYday,$WaterCountReadingTimestampPreviousIsdst) = localtime($WaterCountReadingTimestampPreviousRelative);
  500. my $WaterCountReadingTimestampCurrentRelative = time_str2num($WaterCountReadingTimestampCurrent);
  501. my($WaterCountReadingTimestampCurrentSec,$WaterCountReadingTimestampCurrentMin,$WaterCountReadingTimestampCurrentHour,$WaterCountReadingTimestampCurrentMday,$WaterCountReadingTimestampCurrentMon,$WaterCountReadingTimestampCurrentYear,$WaterCountReadingTimestampCurrentWday,$WaterCountReadingTimestampCurrentYday,$WaterCountReadingTimestampCurrentIsdst) = localtime($WaterCountReadingTimestampCurrentRelative);
  502. ### Correct current month by one month since Unix/Linux start January with 0 instead of 1
  503. $WaterCountReadingTimestampCurrentMon = $WaterCountReadingTimestampCurrentMon + 1;
  504. ### Create Log entries for debugging
  505. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - Reading Name : " . $WaterCountReadingName;
  506. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - Previous Reading Value : " . $WaterCountReadingTimestampPrevious;
  507. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - Current Reading Value : " . $WaterCountReadingTimestampCurrent;
  508. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - Previous Reading Value : " . $WaterCountReadingValuePrevious;
  509. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - Current Reading Value : " . $WaterCountReadingValueCurrent;
  510. ####### Check whether Initial readings needs to be written
  511. ### Check whether the current value is the first one after change of day = First one after midnight
  512. if ($WaterCountReadingTimestampCurrentHour < $WaterCountReadingTimestampPreviousHour)
  513. {
  514. ### Create Log entries for debugging
  515. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - First reading of day detected";
  516. ### Calculate Water Consumption of previous day ? = (Wprevious[qm] - WcurrentDay[qm])
  517. my $WaterCalcConsumptionDayLast = ($WaterCountReadingValuePrevious - ReadingsVal($WaterCalcReadingDestinationDeviceName, $WaterCalcReadingPrefix . "_CounterDay1st", "0"));
  518. ### Calculate pure Water cost of previous day WaterCalcConsumptionDayLast * Price per qm
  519. my $WaterCalcConsumptionCostDayLast = $WaterCalcConsumptionDayLast * $attr{$WaterCalcName}{WaterPricePerCubic};
  520. ### Reload last flow Value
  521. my $WaterCalcWFRCurrent = ReadingsVal($WaterCalcReadingDestinationDeviceName, $WaterCalcReadingPrefix . "_WFRCurrent", "0");
  522. ### Save Water pure cost of previous day, current water Consumption as first reading of day = first after midnight and reset min, max value, value counter and value sum
  523. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_ConsumptionCostDayLast", (sprintf('%.2f', ($WaterCalcConsumptionCostDayLast))), 1);
  524. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_ConsumptionDayLast", (sprintf('%.3f', ($WaterCalcConsumptionDayLast ))), 1);
  525. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_CounterDay1st", (sprintf('%.3f', ($WaterCountReadingValueCurrent ))), 1);
  526. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_CounterDayLast", (sprintf('%.3f', ($WaterCountReadingValuePrevious ))), 1);
  527. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, "." . $WaterCalcReadingPrefix . "_WFRDaySum", 0 , 1);
  528. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, "." . $WaterCalcReadingPrefix . "_WFRDayCount", 0 , 1);
  529. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_WFRDayMin", (sprintf('%.3f', ($WaterCalcWFRCurrent ))), 1);
  530. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_WFRDayMax", 0 , 1);
  531. ### Check whether the current value is the first one after change of month
  532. if ($WaterCountReadingTimestampCurrentMday < $WaterCountReadingTimestampPreviousMday)
  533. {
  534. ### Create Log entries for debugging
  535. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - First reading of month detected";
  536. ### Calculate Water Consumption of previous month ? = (Wprevious[qm] - W1stReadMonth[qm])
  537. my $WaterCalcConsumptionMonthLast = ($WaterCountReadingValuePrevious - ReadingsVal($WaterCalcReadingDestinationDeviceName, $WaterCalcReadingPrefix . "_CounterMonth1st", "0"));
  538. ### Calculate pure Water cost of previous month WaterCalcConsumptionMonthLast * Price per qm
  539. my $WaterCalcConsumptionCostMonthLast = $WaterCalcConsumptionMonthLast * $attr{$WaterCalcName}{WaterPricePerCubic};
  540. ### Save Water Consumption and pure cost of previous month
  541. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_ConsumptionCostMonthLast", (sprintf('%.2f', ($WaterCalcConsumptionCostMonthLast))), 1);
  542. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_ConsumptionMonthLast", (sprintf('%.3f', ($WaterCalcConsumptionMonthLast ))), 1);
  543. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_CounterMonth1st", (sprintf('%.3f', ($WaterCountReadingValueCurrent ))), 1);
  544. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_CounterMonthLast", (sprintf('%.3f', ($WaterCountReadingValuePrevious ))), 1);
  545. ### Check whether the current value is the first one of the meter-reading month
  546. if ($WaterCountReadingTimestampCurrentMon eq $attr{$WaterCalcName}{MonthOfAnnualReading})
  547. {
  548. ### Create Log entries for debugging
  549. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - First reading of month for meter reading detected";
  550. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - Current month is : " . $WaterCountReadingTimestampCurrentMon;
  551. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - Attribute MonthOfAnnualReading is : " . $attr{$WaterCalcName}{MonthOfAnnualReading};
  552. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - Counter1stMeter is : " . $WaterCountReadingValueCurrent;
  553. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - CounterLastMeter is : " . $WaterCountReadingValuePrevious;
  554. ### Calculate Water Consumption of previous meter reading year ? = (Wprevious[qm] - WcurrentMeter[qm])
  555. my $WaterCalcConsumptionMeterLast = ($WaterCountReadingValuePrevious - ReadingsVal($WaterCalcReadingDestinationDeviceName, $WaterCalcReadingPrefix . "_CounterMeter1st", "0"));
  556. ### Calculate pure Water cost of previous meter reading year ? = WaterCalcConsumptionMeterLast * Price per qm
  557. my $WaterCalcConsumptionCostMeterLast = $WaterCalcConsumptionMeterLast * $attr{$WaterCalcName}{WaterPricePerCubic};
  558. ### Save Water Consumption and pure cost of previous meter year
  559. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_ConsumptionCostMeterLast", (sprintf('%.2f', ($WaterCalcConsumptionCostMeterLast ))), 1);
  560. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_ConsumptionMeterLast", (sprintf('%.3f', ($WaterCalcConsumptionMeterLast ))), 1);
  561. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_CounterMeter1st", (sprintf('%.3f', ($WaterCountReadingValueCurrent ))), 1);
  562. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_CounterMeterLast", (sprintf('%.3f', ($WaterCountReadingValuePrevious ))), 1);
  563. }
  564. ### Check whether the current value is the first one of the calendar year
  565. if ($WaterCountReadingTimestampCurrentYear > $WaterCountReadingTimestampPreviousYear)
  566. {
  567. ### Create Log entries for debugging
  568. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - First reading of calendar year detected";
  569. ### Calculate Water Consumption of previous calendar year ? = (Wcurrent[qm] - WcurrentYear[qm])
  570. my $WaterCalcConsumptionYearLast = ($WaterCountReadingValuePrevious - ReadingsVal($WaterCalcReadingDestinationDeviceName, $WaterCalcReadingPrefix . "_CounterYear1st", "0"));
  571. ### Calculate pure Water cost of previous calendar year ? = WaterCalcConsumptionYearLast * Price per qm
  572. my $WaterCalcConsumptionCostYearLast = $WaterCalcConsumptionYearLast * $attr{$WaterCalcName}{WaterPricePerCubic};
  573. ### Save Water Consumption and pure cost of previous calendar year
  574. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_ConsumptionCostYearLast", (sprintf('%.2f', ($WaterCalcConsumptionCostYearLast ))), 1);
  575. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_ConsumptionYearLast", (sprintf('%.3f', ($WaterCalcConsumptionYearLast ))), 1);
  576. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_CounterYear1st", (sprintf('%.3f', ($WaterCountReadingValueCurrent ))), 1);
  577. readingsSingleUpdate( $WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_CounterYearLast", (sprintf('%.3f', ($WaterCountReadingValuePrevious ))), 1);
  578. }
  579. }
  580. }
  581. ###### Do calculations
  582. ### Calculate DtCurrent (time difference) of previous and current timestamp / [s]
  583. my $WaterCountReadingTimestampDelta = $WaterCountReadingTimestampCurrentRelative - $WaterCountReadingTimestampPreviousRelative;
  584. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCountReadingTimestampDelta : " . $WaterCountReadingTimestampDelta . " s";
  585. ### Continue with calculations only if time difference is larger than 10 seconds to avoid "Illegal division by zero" and erroneous due to small values for divisor
  586. if ($WaterCountReadingTimestampDelta > 10)
  587. {
  588. ### Calculate water consumption (water consumption difference) of previous and current value / [qm]
  589. my $WaterCountReadingValueDelta = sprintf('%.3f', ($WaterCountReadingValueCurrent - $WaterCountReadingValuePrevious));
  590. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCountReadingValueDelta : " . $WaterCountReadingValueDelta;
  591. ### Calculate Current water flow rate WFR = DV/Dt[qm/s] * 60[s/min] * 1000 [qm --> l] * WFRUnitFactor
  592. my $WaterCalcWFRCurrent = ($WaterCountReadingValueDelta / $WaterCountReadingTimestampDelta) * 60 * 1000 * $WaterCalcDev->{system}{WFRUnitFactor};
  593. ### Calculate daily sum of water flow measurements "SWFR" and measurement counts "n" and then calculate average water low rate "WFRaverage = SWFR/n"
  594. my $WaterCalcWFRDaySum = ReadingsVal($WaterCalcReadingDestinationDeviceName, "." . $WaterCalcReadingPrefix . "_WFRDaySum", "0") + $WaterCalcWFRCurrent;
  595. my $WaterCalcWFRDayCount = ReadingsVal($WaterCalcReadingDestinationDeviceName, "." . $WaterCalcReadingPrefix . "_WFRDayCount", "0") + 1;
  596. my $WaterCalcWFRDayAverage = $WaterCalcWFRDaySum / $WaterCalcWFRDayCount;
  597. ### Calculate consumed water of current day V = (Vcurrent[qm] - V1stReadDay[qm])
  598. my $WaterCalcConsumptionDay = ($WaterCountReadingValueCurrent - ReadingsVal($WaterCalcReadingDestinationDeviceName, $WaterCalcReadingPrefix . "_CounterDay1st", "0"));
  599. ### Calculate consumed water of current month V = (Vcurrent[qm] - V1stReadMonth[qm])
  600. my $WaterCalcConsumptionMonth = ($WaterCountReadingValueCurrent - ReadingsVal($WaterCalcReadingDestinationDeviceName, $WaterCalcReadingPrefix . "_CounterMonth1st", "0"));
  601. ### Calculate consumed water of current year V = (Vcurrent[qm] - V1stReadYear[qm])
  602. my $WaterCalcConsumptionYear = ($WaterCountReadingValueCurrent - ReadingsVal($WaterCalcReadingDestinationDeviceName, $WaterCalcReadingPrefix . "_CounterYear1st", "0"));
  603. ### Calculate consumed water of Water-meter year V = (Vcurrent[qm] - V1stReadMeter[qm])
  604. my $WaterCalcConsumptionMeter = ($WaterCountReadingValueCurrent - ReadingsVal($WaterCalcReadingDestinationDeviceName, $WaterCalcReadingPrefix . "_CounterMeter1st", "0"));
  605. ### Calculate pure Water cost since midnight
  606. my $WaterCalcConsumptionCostDay = $WaterCalcConsumptionDay * $attr{$WaterCalcName}{WaterPricePerCubic};
  607. ### Calculate pure Water cost since first day of month
  608. my $WaterCalcConsumptionCostMonth = $WaterCalcConsumptionMonth * $attr{$WaterCalcName}{WaterPricePerCubic};
  609. ### Calculate pure Water cost since first day of calendar year
  610. my $WaterCalcConsumptionCostYear = $WaterCalcConsumptionYear * $attr{$WaterCalcName}{WaterPricePerCubic};
  611. ### Calculate pure Water cost since first day of water meter reading year
  612. my $WaterCalcConsumptionCostMeter = $WaterCalcConsumptionMeter * $attr{$WaterCalcName}{WaterPricePerCubic};
  613. ### Calculate the payment month since the year of water meter reading started
  614. my $WaterCalcMeterYearMonth=0;
  615. if (($WaterCountReadingTimestampCurrentMon - $attr{$WaterCalcName}{MonthOfAnnualReading} + 1) < 1)
  616. {
  617. $WaterCalcMeterYearMonth = 13 + $WaterCountReadingTimestampCurrentMon - $attr{$WaterCalcName}{MonthOfAnnualReading};
  618. }
  619. else
  620. {
  621. $WaterCalcMeterYearMonth = 1 + $WaterCountReadingTimestampCurrentMon - $attr{$WaterCalcName}{MonthOfAnnualReading};
  622. }
  623. ### Calculate reserves at Water supplier based on monthly advance payments within year of water meter reading
  624. my $WaterCalcReserves = ($WaterCalcMeterYearMonth * $attr{$WaterCalcName}{MonthlyPayment}) - ($attr{$WaterCalcName}{BasicPricePerAnnum} / 12 * $WaterCalcMeterYearMonth) - $WaterCalcConsumptionCostMeter;
  625. ### Create Log entries for debugging
  626. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - _______Finance________________________________________";
  627. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - Monthly Payment : " . $attr{$WaterCalcName}{MonthlyPayment} . " " . $attr{$WaterCalcName}{Currency};
  628. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - Basic price per annum : " . $attr{$WaterCalcName}{BasicPricePerAnnum} . " " . $attr{$WaterCalcName}{Currency};
  629. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCalcConsumptionCostMeter : " . sprintf('%.2f', ($WaterCalcConsumptionCostMeter)) . " " . $attr{$WaterCalcName}{Currency};
  630. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCalcReserves : " . sprintf('%.3f', ($WaterCalcReserves)) . " " . $attr{$WaterCalcName}{Currency};
  631. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - _______Times__________________________________________";
  632. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCalcMeterYearMonth : " . $WaterCalcMeterYearMonth;
  633. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - Current Month : " . $WaterCountReadingTimestampCurrentMon;
  634. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - _______Consumption_________________________________________";
  635. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCalcConsumptionDay : " . sprintf('%.3f', ($WaterCalcConsumptionDay)) . " qm";
  636. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCalcConsumptionMonth : " . sprintf('%.3f', ($WaterCalcConsumptionMonth)) . " qm";
  637. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCalcConsumptionYear : " . sprintf('%.3f', ($WaterCalcConsumptionYear)) . " qm";
  638. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCalcConsumptionMeter : " . sprintf('%.3f', ($WaterCalcConsumptionMeter)) . " qm";
  639. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - _______flow___________________________________________";
  640. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCalcWFRCurrent : " . sprintf('%.3f', ($WaterCalcWFRCurrent)) . " l_min";
  641. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCalcWFRDayMin : " . ReadingsVal( $WaterCalcReadingDestinationDeviceName, $WaterCalcReadingPrefix . "_WFRDayMin", 0) . " l_min";
  642. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCalcWFRDayAverage : " . sprintf('%.3f', ($WaterCalcWFRDayAverage)) . " l_min";
  643. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCalcWFRDayMax : " . ReadingsVal( $WaterCalcReadingDestinationDeviceName, $WaterCalcReadingPrefix . "_WFRDayMax", 0) . " l_min";
  644. ###### Write readings to WaterCalc device
  645. ### Initialize Bulkupdate
  646. readingsBeginUpdate($WaterCalcReadingDestinationDevice);
  647. ### Write consumed water Consumption (DV) since last measurement
  648. readingsBulkUpdate($WaterCalcReadingDestinationDevice, "." . $WaterCalcReadingPrefix . "_LastDV", sprintf('%.3f', ($WaterCountReadingValueDelta)));
  649. ### Write timelap (Dt) since last measurement
  650. readingsBulkUpdate($WaterCalcReadingDestinationDevice, "." . $WaterCalcReadingPrefix . "_LastDt", sprintf('%.0f', ($WaterCountReadingTimestampDelta)));
  651. ### Write current flow = average flow over last measurement period
  652. readingsBulkUpdate($WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_WFRCurrent", sprintf('%.3f', ($WaterCalcWFRCurrent)));
  653. ### Write daily flow = average flow since midnight
  654. readingsBulkUpdate($WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_WFRDayAver", sprintf('%.3f', ($WaterCalcWFRDayAverage)));
  655. ### Write flow measurement sum since midnight for average calculation
  656. readingsBulkUpdate($WaterCalcReadingDestinationDevice, "." . $WaterCalcReadingPrefix . "_WFRDaySum", sprintf('%.3f', ($WaterCalcWFRDaySum)));
  657. ### Write flow measurement counts since midnight for average calculation
  658. readingsBulkUpdate($WaterCalcReadingDestinationDevice, "." . $WaterCalcReadingPrefix . "_WFRDayCount", sprintf('%.0f', ($WaterCalcWFRDayCount)));
  659. ### Detect new daily minimum flow value and write to reading
  660. if (ReadingsVal($WaterCalcReadingDestinationDeviceName, $WaterCalcReadingPrefix . "_WFRDayMin", 0) > $WaterCalcWFRCurrent)
  661. {
  662. ### Write new minimum flow value
  663. readingsBulkUpdate($WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_WFRDayMin", sprintf('%.0f', ($WaterCalcWFRCurrent)));
  664. ### Create Log entries for debugging
  665. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - New daily minimum flow value detected : " . sprintf('%.3f', ($WaterCalcWFRCurrent));
  666. }
  667. ### Detect new daily maximum flow value and write to reading
  668. if (ReadingsVal($WaterCalcReadingDestinationDeviceName, $WaterCalcReadingPrefix . "_WFRDayMax", 0) < $WaterCalcWFRCurrent)
  669. {
  670. ### Write new maximum flow value
  671. readingsBulkUpdate($WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_WFRDayMax", sprintf('%.3f', ($WaterCalcWFRCurrent)));
  672. ### Create Log entries for debugging
  673. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - New daily maximum flow value detected : " . sprintf('%.3f', ($WaterCalcWFRCurrent));
  674. }
  675. ### Write Consumption consumption since midnight
  676. readingsBulkUpdate($WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_ConsumptionDay", sprintf('%.3f', ($WaterCalcConsumptionDay)));
  677. ### Write Consumption consumption since beginning of month
  678. readingsBulkUpdate($WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_ConsumptionMonth", sprintf('%.3f', ($WaterCalcConsumptionMonth)));
  679. ### Write Consumption consumption since beginning of year
  680. readingsBulkUpdate($WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_ConsumptionYear", sprintf('%.3f', ($WaterCalcConsumptionYear)));
  681. ### Write Consumption consumption since last meter reading
  682. readingsBulkUpdate($WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_ConsumptionMeter", sprintf('%.3f', ($WaterCalcConsumptionMeter)));
  683. ### Write pure Consumption costs since midnight
  684. readingsBulkUpdate($WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_ConsumptionCostDay", sprintf('%.2f', ($WaterCalcConsumptionCostDay)));
  685. ### Write pure Consumption costs since beginning of month
  686. readingsBulkUpdate($WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_ConsumptionCostMonth", sprintf('%.2f', ($WaterCalcConsumptionCostMonth)));
  687. ### Write pure Consumption costs since beginning of calendar year
  688. readingsBulkUpdate($WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_ConsumptionCostYear", sprintf('%.2f', ($WaterCalcConsumptionCostYear)));
  689. ### Write pure Consumption costs since beginning of year of water meter reading
  690. readingsBulkUpdate($WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_ConsumptionCostMeter", sprintf('%.2f', ($WaterCalcConsumptionCostMeter)));
  691. ### Write reserves at Water supplier based on monthly advance payments within year of water meter reading
  692. readingsBulkUpdate($WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_FinanceReserve", sprintf('%.3f', ($WaterCalcReserves)));
  693. ### Write current meter reading as sshown on the mechanical meter
  694. readingsBulkUpdate($WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_CounterCurrent", sprintf('%.3f', ($WaterCountReadingValueCurrent)));
  695. ### Write months since last meter reading
  696. readingsBulkUpdate($WaterCalcReadingDestinationDevice, $WaterCalcReadingPrefix . "_MonthMeterReading", sprintf('%.0f', ($WaterCalcMeterYearMonth)));
  697. ### Finish and execute Bulkupdate
  698. readingsEndUpdate($WaterCalcReadingDestinationDevice, 1);
  699. }
  700. else
  701. {
  702. ### Create Log entries for debugging
  703. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - WaterCountReadingTimestampDelta = $WaterCountReadingTimestampDelta. Calculations skipped!";
  704. }
  705. ### Create Log entries for debugging
  706. Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator End_________________________________________________________________________________________________________________________________";
  707. }
  708. ### If readings exist, update list of available readings
  709. if($WaterCalcDev->{READINGS})
  710. {
  711. ### Copy readings in list of available "gets" and "sets"
  712. %{$WaterCalcDev->{helper}{gets}} = %{$WaterCalcDev->{READINGS}};
  713. %{$WaterCalcDev->{helper}{sets}} = %{$WaterCalcDev->{READINGS}};
  714. ### Create Log entries for debugging
  715. #Log3 $WaterCalcName, 5, $WaterCalcName. " : WaterCalculator - notify x_sets list: " . join(" ", (keys %{$WaterCalcDev->{helper}{sets}}));
  716. }
  717. return undef;
  718. }
  719. ####END####### Calculate water meter values on changed events ####################################################END#####
  720. 1;
  721. ###START###### Description for fhem commandref ################################################################START####
  722. =pod
  723. =item helper
  724. =item summary Calculates the water consumption and costs
  725. =item summary_DE Berechnet den Wasserverbrauch und verbundene Kosten
  726. =begin html
  727. <a name="WaterCalculator"></a>
  728. <h3>WaterCalculator</h3>
  729. <ul>
  730. <table>
  731. <tr>
  732. <td>
  733. The WaterCalculator Module calculates the water consumption and costs of one or more water meters.<BR>
  734. It is not a counter module itself but it requires a regular expression (regex or regexp) in order to know where to retrieve the counting ticks of one or more mechanical or electronic water meter.<BR>
  735. <BR>
  736. <BR>
  737. <FONT COLOR="#FF0000">The function of the sub-counter for garden water has not been implemented yet. Therefore the sewage water cost needs to be taken into account.</FONT>
  738. <BR>
  739. As soon the module has been defined within the fhem.cfg, the module reacts on every event of the specified counter like myOWDEVICE:counter.* etc.<BR>
  740. <BR>
  741. The WaterCalculator module provides several current, historical, statistical values around with respect to one or more water meter and creates respective readings.<BR>
  742. <BR>
  743. To avoid waiting for max. 12 months to have realistic values, the readings <BR>
  744. <code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterDay1st</code>,<BR>
  745. <code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterMonth1st</code>,<BR>
  746. <code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterYear1st</code> and<BR>
  747. <code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterMeter1st</code><BR>
  748. must be corrected with real values by using the <code>setreading</code> - command.<BR>
  749. These real values may be found on the last water bill. Otherwise it will take 24h for the daily, 30days for the monthly and up to 12 month for the yearly values to become realistic.<BR>
  750. <BR>
  751. Intervalls smaller than 10s will be discarded to avoid peaks due to fhem blockages (e.g. DbLog - reducelog).
  752. <BR>
  753. </td>
  754. </tr>
  755. </table>
  756. <table><tr><td><a name="WaterCalculatorDefine"></a><b>Define</b></td></tr></table>
  757. <table><tr><td><ul><code>define &lt;name&gt; WaterCalculator &lt;regex&gt;</code></ul></td></tr></table>
  758. <ul><ul>
  759. <table>
  760. <tr><td><code>&lt;name&gt;</code> : </td><td>The name of the calculation device. (E.g.: "myWaterCalculator")</td></tr>
  761. <tr><td><code>&lt;regex&gt;</code> : </td><td>A valid regular expression (also known as regex or regexp) of the event where the counter can be found</td></tr>
  762. </table>
  763. </ul></ul>
  764. <table><tr><td><ul>Example: <code>define myWaterCalculator WaterCalculator myWaterCounter:countersA.*</code></ul></td></tr></table>
  765. <BR>
  766. <table>
  767. <tr><td><a name="WaterCalculatorSet"></a><b>Set</b></td></tr>
  768. <tr><td>
  769. <ul>
  770. The set - function sets individual values for example to correct values after power loss etc.<BR>
  771. The set - function works only for readings which have been stored in the CalculatorDevice.<BR>
  772. The Readings being stored in the Counter - Device need to be changed individially with the <code>set</code> - command.<BR>
  773. </ul>
  774. </td></tr>
  775. </table>
  776. <BR>
  777. <table>
  778. <tr><td><a name="WaterCalculatorGet"></a><b>Get</b></td></tr>
  779. <tr><td>
  780. <ul>
  781. The get - function just returns the individual value of the reading.<BR>
  782. The get - function works only for readings which have been stored in the CalculatorDevice.<BR>
  783. The Readings being stored in the Counter - Device need to be read individially with <code>get</code> - command.<BR>
  784. </ul>
  785. </td></tr>
  786. </table>
  787. <BR>
  788. <table>
  789. <tr><td><a name="WaterCalculatorAttr"></a><b>Attributes</b></td></tr>
  790. <tr><td>
  791. <ul>
  792. If the below mentioned attributes have not been pre-defined completly beforehand, the program will create the WaterCalculator specific attributes with default values.<BR>
  793. In addition the global attributes e.g. <a href="#room">room</a> can be used.<BR>
  794. </ul>
  795. </td></tr>
  796. </table>
  797. <ul><ul>
  798. <table>
  799. <tr>
  800. <td>
  801. <tr><td><li><code>BasicPricePerAnnum</code> : </li></td><td> A valid float number for basic annual fee in the chosen currency for the water supply to the home.<BR>
  802. The value is provided by your local water supplier and is shown on your water bill.<BR>
  803. For UK and US users it may known under "standing charge". Please make sure it is based on one year!<BR>
  804. The default value is 0.00<BR>
  805. </td></tr>
  806. </td>
  807. </tr>
  808. </table>
  809. </ul></ul>
  810. <ul><ul>
  811. <table>
  812. <tr>
  813. <td>
  814. <tr><td><li><code>Currency</code> : </li></td><td> One of the pre-defined list of currency symbols [&#8364;,&#163;,&#36;].<BR>
  815. The default value is &#8364;<BR>
  816. </td></tr>
  817. </td>
  818. </tr>
  819. </table>
  820. </ul></ul>
  821. <ul><ul>
  822. <table>
  823. <tr>
  824. <td>
  825. <tr><td><li><code>disable</code> : </li></td><td> Disables the current module. The module will not react on any events described in the regular expression.<BR>
  826. The default value is 0 = enabled.<BR>
  827. </td></tr>
  828. </td>
  829. </tr>
  830. </table>
  831. </ul></ul>
  832. <ul><ul>
  833. <table>
  834. <tr>
  835. <td>
  836. <tr><td><li><code>WaterCounterOffset</code> : </li></td><td> A valid float number of the water Consumption difference = offset (not the difference of the counter ticks!) between the value shown on the mechanic meter for the water consumption and the calculated water consumption of the counting device.<BR>
  837. The value for this offset will be calculated as follows W<sub>Offset</sub> = W<sub>Mechanical</sub> - W<sub>Module</sub><BR>
  838. The default value is 0.00<BR>
  839. </td></tr>
  840. </td>
  841. </tr>
  842. </table>
  843. </ul></ul>
  844. <ul><ul>
  845. <table>
  846. <tr>
  847. <td>
  848. <tr><td><li><code>WaterCubicPerCounts</code> : </li></td><td> A valid float number of water consumption in qm per counting ticks.<BR>
  849. The value is given by the mechanical trigger of the mechanical water meter. E.g. WaterCubicPerCounts = 0.001 means each count is a thousandth of one qm (=liter).<BR>
  850. The default value is 1 (= the counter is already providing qm)<BR>
  851. </td></tr>
  852. </td>
  853. </tr>
  854. </table>
  855. </ul></ul>
  856. <ul><ul>
  857. <table>
  858. <tr>
  859. <td>
  860. <tr><td><li><code>WaterPricePerCubic</code> : </li></td><td> A valid float number for water Consumption price in the chosen currency per qm.<BR>
  861. <FONT COLOR="#FF0000">The sewage water cost needs to be taken into account.</FONT>
  862. The value is provided by your local water supplier and is shown on your water bill.<BR>
  863. The default value is 2.00<BR>
  864. </td></tr>
  865. </td>
  866. </tr>
  867. </table>
  868. </ul></ul>
  869. <ul><ul>
  870. <table>
  871. <tr>
  872. <td>
  873. <tr><td><li><code>MonthlyPayment</code> : </li></td><td> A valid float number for monthly advance payments in the chosen currency towards the water supplier.<BR>
  874. The default value is 0.00<BR>
  875. </td></tr>
  876. </td>
  877. </tr>
  878. </table>
  879. </ul></ul>
  880. <ul><ul>
  881. <table>
  882. <tr>
  883. <td>
  884. <tr><td><li><code>MonthOfAnnualReading</code> : </li></td><td> A valid integer number for the month when the mechanical water meter reading is performed every year.<BR>
  885. The default value is 5 (May)<BR>
  886. </td></tr>
  887. </td>
  888. </tr>
  889. </table>
  890. </ul></ul>
  891. <ul><ul>
  892. <table>
  893. <tr>
  894. <td>
  895. <tr><td><li><code>ReadingDestination</code> : </li></td><td> One of the pre-defined list for the destination of the calculated readings: [CalculatorDevice,CounterDevice].<BR>
  896. The CalculatorDevice is the device which has been created with this module.<BR>
  897. The CounterDevice is the Device which is reading the mechanical Water-meter.<BR>
  898. The default value is CalculatorDevice - Therefore the readings will be written into this device.<BR>
  899. </td></tr>
  900. </td>
  901. </tr>
  902. </table>
  903. </ul></ul>
  904. <ul><ul>
  905. <table>
  906. <tr>
  907. <td>
  908. <tr><td><li><code>WFRUnit</code> : </li></td><td> One value of the pre-defined list: l/min (liter/minute), m&sup3;/min (cubicmeter/minute), m&sup3;/h (cubicmeter/hour).<BR>
  909. It defines which unit shall be used and devides the water flow rate accordingly.<BR>
  910. The default value is l/min (liter/minute).<BR>
  911. </td></tr>
  912. </td>
  913. </tr>
  914. </table>
  915. </ul></ul>
  916. <BR>
  917. <table>
  918. <tr><td><a name="WaterCalculatorReadings"></a><b>Readings</b></td></tr>
  919. <tr><td>
  920. <ul>
  921. As soon the device has been able to read at least 2 times the counter, it automatically will create a set of readings:<BR>
  922. The placeholder <code>&lt;DestinationDevice&gt;</code> is the device which has been chosen in the attribute <code>ReadingDestination</code> above. <BR> This will not appear if CalculatorDevice has been chosen.<BR>
  923. The placeholder <code>&lt;SourceCounterReading&gt;</code> is the reading based on the defined regular expression where the counting ticks are coming from.<BR>
  924. </ul>
  925. </td></tr>
  926. </table>
  927. <ul><ul>
  928. <table>
  929. <tr>
  930. <td>
  931. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterCurrent</code> : </li></td><td>Current indicated total water consumption as shown on mechanical water meter. Correct Offset-attribute if not identical.<BR>
  932. </td></tr>
  933. </td>
  934. </tr>
  935. </table>
  936. </ul></ul>
  937. <ul><ul>
  938. <table>
  939. <tr>
  940. <td>
  941. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterDay1st</code> : </li></td><td>The first meter reading after midnight.<BR>
  942. </td></tr>
  943. </td>
  944. </tr>
  945. </table>
  946. </ul></ul>
  947. <ul><ul>
  948. <table>
  949. <tr>
  950. <td>
  951. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterDayLast</code> : </li></td><td>The last meter reading of the previous day.<BR>
  952. </td></tr>
  953. </td>
  954. </tr>
  955. </table>
  956. </ul></ul>
  957. <ul><ul>
  958. <table>
  959. <tr>
  960. <td>
  961. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterMonth1st</code> : </li></td><td>The first meter reading after midnight of the first day of the month.<BR>
  962. </td></tr>
  963. </td>
  964. </tr>
  965. </table>
  966. </ul></ul>
  967. <ul><ul>
  968. <table>
  969. <tr>
  970. <td>
  971. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterMonthLast</code> : </li></td><td>The last meter reading of the previous month.<BR>
  972. </td></tr>
  973. </td>
  974. </tr>
  975. </table>
  976. </ul></ul>
  977. <ul><ul>
  978. <table>
  979. <tr>
  980. <td>
  981. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterMeter1st</code> : </li></td><td>The first meter reading after midnight of the first day of the month where the mechanical meter is read by the Water supplier.<BR>
  982. </td></tr>
  983. </td>
  984. </tr>
  985. </table>
  986. </ul></ul>
  987. <ul><ul>
  988. <table>
  989. <tr>
  990. <td>
  991. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterMeterLast</code> : </li></td><td>The last meter reading of the previous meter reading year.<BR>
  992. </td></tr>
  993. </td>
  994. </tr>
  995. </table>
  996. </ul></ul>
  997. <ul><ul>
  998. <table>
  999. <tr>
  1000. <td>
  1001. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterYear1st</code> : </li></td><td>The first meter reading after midnight of the first day of the year.<BR>
  1002. </td></tr>
  1003. </td>
  1004. </tr>
  1005. </table>
  1006. </ul></ul>
  1007. <ul><ul>
  1008. <table>
  1009. <tr>
  1010. <td>
  1011. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterYearLast</code> : </li></td><td>The last meter reading of the previous year.<BR>
  1012. </td></tr>
  1013. </td>
  1014. </tr>
  1015. </table>
  1016. </ul></ul>
  1017. <ul><ul>
  1018. <table>
  1019. <tr>
  1020. <td>
  1021. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionCostDayLast</code> : </li></td><td>Consumption costs of the last day.<BR>
  1022. </td></tr>
  1023. </td>
  1024. </tr>
  1025. </table>
  1026. </ul></ul>
  1027. <ul><ul>
  1028. <table>
  1029. <tr>
  1030. <td>
  1031. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionCostMeterLast</code> : </li></td><td>Consumption costs in the chosen currency of the last water meter period.<BR>
  1032. </td></tr>
  1033. </td>
  1034. </tr>
  1035. </table>
  1036. </ul></ul>
  1037. <ul><ul>
  1038. <table>
  1039. <tr>
  1040. <td>
  1041. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionCostMonthLast</code> : </li></td><td>Consumption costs in the chosen currency of the last month.<BR>
  1042. </td></tr>
  1043. </td>
  1044. </tr>
  1045. </table>
  1046. </ul></ul>
  1047. <ul><ul>
  1048. <table>
  1049. <tr>
  1050. <td>
  1051. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionCostYearLast</code> : </li></td><td>Consumption costs of the last calendar year.<BR>
  1052. </td></tr>
  1053. </td>
  1054. </tr>
  1055. </table>
  1056. </ul></ul>
  1057. <ul><ul>
  1058. <table>
  1059. <tr>
  1060. <td>
  1061. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionCostDay</code> : </li></td><td>Consumption costs in the chosen currency since the beginning of the current day.<BR>
  1062. </td></tr>
  1063. </td>
  1064. </tr>
  1065. </table>
  1066. </ul></ul>
  1067. <ul><ul>
  1068. <table>
  1069. <tr>
  1070. <td>
  1071. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionCostMeter</code> : </li></td><td>Consumption costs in the chosen currency since the beginning of the month of where the last water meter reading has been performed by the Water supplier.<BR>
  1072. </td></tr>
  1073. </td>
  1074. </tr>
  1075. </table>
  1076. </ul></ul>
  1077. <ul><ul>
  1078. <table>
  1079. <tr>
  1080. <td>
  1081. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionCostMonth</code> : </li></td><td>Consumption costs in the chosen currency since the beginning of the current month.<BR>
  1082. </td></tr>
  1083. </td>
  1084. </tr>
  1085. </table>
  1086. </ul></ul>
  1087. <ul><ul>
  1088. <table>
  1089. <tr>
  1090. <td>
  1091. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionCostYear</code> : </li></td><td>Consumption costs in the chosen currency since the beginning of the current year.<BR>
  1092. </td></tr>
  1093. </td>
  1094. </tr>
  1095. </table>
  1096. </ul></ul>
  1097. <ul><ul>
  1098. <table>
  1099. <tr>
  1100. <td>
  1101. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionDay</code> : </li></td><td>Consumption in qm since the beginning of the current day (midnight).<BR>
  1102. </td></tr>
  1103. </td>
  1104. </tr>
  1105. </table>
  1106. </ul></ul>
  1107. <ul><ul>
  1108. <table>
  1109. <tr>
  1110. <td>
  1111. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionDayLast</code> : </li></td><td>Total Consumption in qm of the last day.<BR>
  1112. </td></tr>
  1113. </td>
  1114. </tr>
  1115. </table>
  1116. </ul></ul>
  1117. <ul><ul>
  1118. <table>
  1119. <tr>
  1120. <td>
  1121. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionMeter</code> : </li></td><td>Consumption in qm since the beginning of the month of where the last Water-meter reading has been performed by the Water supplier.<BR>
  1122. </td></tr>
  1123. </td>
  1124. </tr>
  1125. </table>
  1126. </ul></ul>
  1127. <ul><ul>
  1128. <table>
  1129. <tr>
  1130. <td>
  1131. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionMeterLast</code> : </li></td><td>Total Consumption in qm of the last Water-meter reading period.<BR>
  1132. </td></tr>
  1133. </td>
  1134. </tr>
  1135. </table>
  1136. </ul></ul>
  1137. <ul><ul>
  1138. <table>
  1139. <tr>
  1140. <td>
  1141. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionMonth</code> : </li></td><td>Consumption in qm since the beginning of the current month (midnight of the first).<BR>
  1142. </td></tr>
  1143. </td>
  1144. </tr>
  1145. </table>
  1146. </ul></ul>
  1147. <ul><ul>
  1148. <table>
  1149. <tr>
  1150. <td>
  1151. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionMonthLast</code> : </li></td><td>Total Consumption in qm of the last month.<BR>
  1152. </td></tr>
  1153. </td>
  1154. </tr>
  1155. </table>
  1156. </ul></ul>
  1157. <ul><ul>
  1158. <table>
  1159. <tr>
  1160. <td>
  1161. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionYear</code> : </li></td><td>Consumption in qm since the beginning of the current year (midnight of the first).<BR>
  1162. </td></tr>
  1163. </td>
  1164. </tr>
  1165. </table>
  1166. </ul></ul>
  1167. <ul><ul>
  1168. <table>
  1169. <tr>
  1170. <td>
  1171. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionYearLast</code> : </li></td><td>Total Consumption in qm of the last calendar year.<BR>
  1172. </td></tr>
  1173. </td>
  1174. </tr>
  1175. </table>
  1176. </ul></ul>
  1177. <ul><ul>
  1178. <table>
  1179. <tr>
  1180. <td>
  1181. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_FinanceReserve</code> : </li></td><td>Financial Reserve based on the advanced payments done on the first of every month towards the water supplier. With negative values, an additional payment is to be expected.<BR>
  1182. </td></tr>
  1183. </td>
  1184. </tr>
  1185. </table>
  1186. </ul></ul>
  1187. <ul><ul>
  1188. <table>
  1189. <tr>
  1190. <td>
  1191. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_MonthMeterReading</code> : </li></td><td>Number of month since last meter reading. The month when the reading occured is the first month = 1.<BR>
  1192. </td></tr>
  1193. </td>
  1194. </tr>
  1195. </table>
  1196. </ul></ul>
  1197. <ul><ul>
  1198. <table>
  1199. <tr>
  1200. <td>
  1201. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_WFRCurrent</code> : </li></td><td>Current water flow rate. (water flow rate based on current and previous measurement.)<BR>
  1202. </td></tr>
  1203. </td>
  1204. </tr>
  1205. </table>
  1206. </ul></ul>
  1207. <ul><ul>
  1208. <table>
  1209. <tr>
  1210. <td>
  1211. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_WFRDayAver</code> : </li></td><td>Average water flow rate since midnight.<BR>
  1212. </td></tr>
  1213. </td>
  1214. </tr>
  1215. </table>
  1216. </ul></ul>
  1217. <ul><ul>
  1218. <table>
  1219. <tr>
  1220. <td>
  1221. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_WFRDayMax</code> : </li></td><td>Maximum water flow rate peak since midnight.<BR>
  1222. </td></tr>
  1223. </td>
  1224. </tr>
  1225. </table>
  1226. </ul></ul>
  1227. <ul><ul>
  1228. <table>
  1229. <tr>
  1230. <td>
  1231. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_WFRDayMin</code> : </li></td><td>Minimum water flow rate peak since midnight.<BR>
  1232. </td></tr>
  1233. </td>
  1234. </tr>
  1235. </table>
  1236. </ul></ul>
  1237. </ul>
  1238. =end html
  1239. =begin html_DE
  1240. <a name="WaterCalculator"></a>
  1241. <h3>WaterCalculator</h3>
  1242. <ul>
  1243. <table>
  1244. <tr>
  1245. <td>
  1246. Das WaterCalculator Modul berechnet den Verbrauch an Wasser und die verbundenen Kosten von einem oder mehreren Wasserz&auml;hlern.<BR>
  1247. <BR>
  1248. <FONT COLOR="#FF0000">Die Funktion des sogenannten Unterwasserz&auml;hlers ist noch nicht implementiert. Daher müssen bei den Wasserkosten die Abwasserkosten mit einbezogen werden.</FONT>
  1249. <BR>
  1250. Es ist kein eigenes Z&auml;hlermodul sondern ben&ouml;tigt eine Regular Expression (regex or regexp) um das Reading mit den Z&auml;hlimpulse von einem oder mehreren Wasserz&auml;hlern zu finden.<BR>
  1251. <BR>
  1252. Sobald das Modul in der fhem.cfg definiert wurde, reagiert das Modul auf jedes durch das regex definierte event wie beispielsweise ein myOWDEVICE:counter.* etc.<BR>
  1253. <BR>
  1254. Das WaterCalculator Modul berechnet augenblickliche, historische statistische und vorhersehbare Werte von einem oder mehreren Wasserz&auml;hlern und erstellt die entsprechenden Readings.<BR>
  1255. <BR>
  1256. Um zu verhindern, dass man bis zu 12 Monate warten muss, bis alle Werte der Realit&auml;t entsprechen, m&uuml;ssen die Readings<BR>
  1257. <code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterDay1st</code>,<BR>
  1258. <code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterMonth1st</code>,<BR>
  1259. <code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterYear1st</code> und<BR>
  1260. <code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterMeter1st</code><BR>
  1261. entsprechend mit dem <code>setreading</code> - Befehl korrigiert werden.<BR>
  1262. Diese Werte findet man unter Umst&auml;nden auf der letzten Abrechnung des Wasserversorgers. Andernfalls dauert es bis zu 24h f&uuml;r die t&auml;glichen, 30 Tage f&uuml;r die monatlichen und bis zu 12 Monate f&uuml;r die j&auml;hrlichen Werte bis diese der Realit&auml;t entsprechen.<BR>
  1263. <BR>
  1264. <BR>
  1265. Intervalle kleienr als 10s werden ignoriert um Spitzen zu verhindern die von Blockaden des fhem Systems hervorgerufen werden (z.B. DbLog - reducelog).
  1266. </td>
  1267. </tr>
  1268. </table>
  1269. <table>
  1270. <tr><td><a name="WaterCalculatorDefine"></a><b>Define</b></td></tr>
  1271. </table>
  1272. <table><tr><td><ul><code>define &lt;name&gt; WaterCalculator &lt;regex&gt;</code></ul></td></tr></table>
  1273. <ul><ul>
  1274. <table>
  1275. <tr><td><code>&lt;name&gt;</code> : </td><td>Der Name dieses Berechnungs-Device. Empfehlung: "myWaterCalculator".</td></tr>
  1276. <tr><td><code>&lt;regex&gt;</code> : </td><td>Eine g&uuml;ltige Regular Expression (regex or regexp) von dem Event wo der Z&auml;hlerstand gefunden werden kann</td></tr>
  1277. </table>
  1278. </ul></ul>
  1279. <table><tr><td><ul>Beispiel: <code>define myWaterCalculator WaterCalculator myWaterCounter:countersA.*</code></ul></td></tr></table>
  1280. <BR>
  1281. <table>
  1282. <tr><td><a name="WaterCalculatorSet"></a><b>Set</b></td></tr>
  1283. <tr><td>
  1284. <ul>
  1285. Die set - Funktion erlaubt individuelle Readings zu ver&auml;ndern um beispielsweise nach einem Stromausfall Werte zu korrigieren.<BR>
  1286. Die set - Funktion funktioniert nur f&uumlr Readings welche im CalculatorDevice gespeichert wurden.<BR>
  1287. Die Readings welche im Counter - Device gespeichert wurden, m&uumlssen individuell mit <code>set</code> - Befehl gesetzt werden.<BR>
  1288. </ul>
  1289. </td></tr>
  1290. </table>
  1291. <BR>
  1292. <table>
  1293. <tr><td><a name="WaterCalculatorGet"></a><b>Get</b></td></tr>
  1294. <tr><td>
  1295. <ul>
  1296. Die get - Funktion liefert nur den Wert des jeweiligen Readings zur&uuml;ck.<BR>
  1297. Die get - Funktion funktioniert nur f&uumlr Readings welche im CalculatorDevice gespeichert wurden.<BR>
  1298. Die Readings welche im Counter - Device gespeichert wurden, m&uumlssen individuell mit <code>get</code> - Befehl ausgelesen werden.<BR>
  1299. </ul>
  1300. </td></tr>
  1301. </table>
  1302. <BR>
  1303. <table>
  1304. <tr><td><a name="WaterCalculatorAttr"></a><b>Attributes</b></td></tr>
  1305. <tr><td>
  1306. <ul>
  1307. Sollten die unten ausfeg&auuml;hrten Attribute bei der Definition eines entsprechenden Ger&auml;tes nicht gesetzt sein, so werden sie vom Modul mit Standard Werten automatisch gesetzt<BR>
  1308. Zus&auml;tzlich k&ouml;nnen die globalen Attribute wie <a href="#room">room</a> verwendet werden.<BR>
  1309. </ul>
  1310. </td></tr>
  1311. </table>
  1312. <ul><ul>
  1313. <table>
  1314. <tr>
  1315. <td>
  1316. <tr><td><li><code>BasicPricePerAnnum</code> : </li></td><td> Eine g&uuml;ltige float Zahl f&uuml;r die j&auml;hrliche Grundgeb&uuml;hr in der gew&auml;hlten W&auml;hrung f&uuml;r die Wasser-Versorgung zum Endverbraucher.<BR>
  1317. Dieser Wert stammt vom Wasserversorger und steht auf der Abrechnung.<BR>
  1318. Der Standard Wert ist 0.00<BR>
  1319. </td></tr>
  1320. </td>
  1321. </tr>
  1322. </table>
  1323. </ul></ul>
  1324. <ul><ul>
  1325. <table>
  1326. <tr>
  1327. <td>
  1328. <tr><td><li><code>Currency</code> : </li></td><td> Eines der vordefinerten W&auml;hrungssymbole: [&#8364;,&#163;,&#36;].<BR>
  1329. Der Standard Wert ist &#8364;<BR>
  1330. </td></tr>
  1331. </td>
  1332. </tr>
  1333. </table>
  1334. </ul></ul>
  1335. <ul><ul>
  1336. <table>
  1337. <tr>
  1338. <td>
  1339. <tr><td><li><code>disable</code> : </li></td><td> Deaktiviert das device. Das Modul wird nicht mehr auf die Events reagieren die durch die Regular Expression definiert wurde.<BR>
  1340. Der Standard Wert ist 0 = aktiviert.<BR>
  1341. </td></tr>
  1342. </td>
  1343. </tr>
  1344. </table>
  1345. </ul></ul>
  1346. <ul><ul>
  1347. <table>
  1348. <tr>
  1349. <td>
  1350. <tr><td><li><code>WaterCounterOffset</code> : </li></td><td> Eine g&uuml;ltige float-Zahl f&uuml;r den Unterschied = Offset (Nicht der Unterschied zwischen Z&auml;hlimpulsen) zwischen dem am mechanischen Wasserz&auml;hlern und dem angezeigten Wert im Reading dieses Device.<BR>
  1351. Der Offset-Wert wird wie folgt ermittelt: W<sub>Offset</sub> = W<sub>Mechanisch</sub> - W<sub>Module</sub><BR>
  1352. Der Standard-Wert ist 0.00<BR>
  1353. </td></tr>
  1354. </td>
  1355. </tr>
  1356. </table>
  1357. </ul></ul>
  1358. <ul><ul>
  1359. <table>
  1360. <tr>
  1361. <td>
  1362. <tr><td><li><code>WaterCubicPerCounts</code> : </li></td><td> Eine g&uuml;ltige float-Zahl f&uuml;r die Menge Kubik pro Z&auml;hlimpulsen.<BR>
  1363. Der Wert ist durch das mechanische Z&auml;hlwerk des Wasserz&auml;hlern vorgegeben. WaterCubicPerCounts = 0.001 bedeutet, dass jeder Z&auml;hlimpuls ein Tausendstel eines Kubik ist (=Liter).<BR>
  1364. Der Standard-Wert ist 1<BR>
  1365. </td></tr>
  1366. </td>
  1367. </tr>
  1368. </table>
  1369. </ul></ul>
  1370. <ul><ul>
  1371. <table>
  1372. <tr>
  1373. <td>
  1374. <tr><td><li><code>WaterPricePerCubic</code> : </li></td><td> Eine g&uuml;ltige float-Zahl f&uuml;r den Preis pro Kubik Wasser.<BR>
  1375. <FONT COLOR="#FF0000">Hierbei müssen die Abwasserkosten mit einbezogen werden.</FONT>
  1376. Dieser Wert stammt vom Wasserversorger und steht auf der Abrechnung.<BR>
  1377. Der Standard-Wert ist 2.00<BR>
  1378. </td></tr>
  1379. </td>
  1380. </tr>
  1381. </table>
  1382. </ul></ul>
  1383. <ul><ul>
  1384. <table>
  1385. <tr>
  1386. <td>
  1387. <tr><td><li><code>MonthlyPayment</code> : </li></td><td> Eine g&uuml;ltige float-Zahl f&uuml;r die monatlichen Abschlagszahlungen in der gew&auml;hlten W&auml;hrung an den Wasserversorger.<BR>
  1388. Der Standard-Wert ist 0.00<BR>
  1389. </td></tr>
  1390. </td>
  1391. </tr>
  1392. </table>
  1393. </ul></ul>
  1394. <ul><ul>
  1395. <table>
  1396. <tr>
  1397. <td>
  1398. <tr><td><li><code>MonthOfAnnualReading</code> : </li></td><td> Eine g&uuml;ltige Ganz-Zahl f&uuml;r den Monat wenn der mechanische Wasserz&auml;hler jedes Jahr durch den Wasserversorger abgelesen wird.<BR>
  1399. Der Standard-Wert ist 5 (Mai)<BR>
  1400. </td></tr>
  1401. </td>
  1402. </tr>
  1403. </table>
  1404. </ul></ul>
  1405. <ul><ul>
  1406. <table>
  1407. <tr>
  1408. <td>
  1409. <tr><td><li><code>ReadingDestination</code> : </li></td><td> Eines der vordefinerten Device als Ziel der errechneten Readings: [CalculatorDevice,CounterDevice].<BR>
  1410. Das CalculatorDevice ist das mit diesem Modul erstellte Device.<BR>
  1411. Das CounterDevice ist das Device von welchem der mechanische Z&auml;hler ausgelesen wird.<BR>
  1412. Der Standard-Wert ist CalculatorDevice.<BR>
  1413. </td></tr>
  1414. </td>
  1415. </tr>
  1416. </table>
  1417. </ul></ul>
  1418. <ul><ul>
  1419. <table>
  1420. <tr>
  1421. <td>
  1422. <tr><td><li><code>WFRUnit</code> : </li></td><td> Ein Wert der vorgegebenen Auswahlliste: l/min (Liter/Minute), m&sup3;/min (Kubikmeter/Minute), m&sup3;/h (Kubikmeter/Stunde).<BR>
  1423. Es definiert welcher Einheit verwendet werden soll und teilt den Wasserdurchsatz entsprechend.<BR>
  1424. Der Standard-Wert ist l/min (Liter/Minute).<BR>
  1425. </td></tr>
  1426. </td>
  1427. </tr>
  1428. </table>
  1429. </ul></ul>
  1430. <BR>
  1431. <table>
  1432. <tr><td><a name="WaterCalculatorReadings"></a><b>Readings</b></td></tr>
  1433. <tr><td>
  1434. <ul>
  1435. Sobald das Device in der Lage war mindestens 2 Werte des Z&auml;hlers einzulesen, werden automatisch die entsprechenden Readings erzeugt:<BR>
  1436. Der Platzhalter <code>&lt;DestinationDevice&gt;</code> steht f&uuml;r das Device, welches man in dem Attribut <code>ReadingDestination</code> oben festgelegt hat. Dieser Platzhalter bleibt leer, sobald man dort CalculatorDevice ausgew&auml;hlt hat.<BR>
  1437. Der Platzhalter <code>&lt;SourceCounterReading&gt;</code> steht f&uuml;r das Reading welches mit der Regular Expression definiert wurde.<BR>
  1438. </ul>
  1439. </td></tr>
  1440. </table>
  1441. <ul><ul>
  1442. <table>
  1443. <tr>
  1444. <td>
  1445. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterCurrent</code> : </li></td><td>Aktueller Z&auml;hlerstand am mechanischen Z&auml;hler. Bei Unterschied muss das Offset-Attribut entspechend korrigiert werden.<BR>
  1446. </td></tr>
  1447. </td>
  1448. </tr>
  1449. </table>
  1450. </ul></ul>
  1451. <ul><ul>
  1452. <table>
  1453. <tr>
  1454. <td>
  1455. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterDay1st</code> : </li></td><td>Der erste Z&auml;hlerstand des laufenden Tages seit Mitternacht.<BR>
  1456. </td></tr>
  1457. </td>
  1458. </tr>
  1459. </table>
  1460. </ul></ul>
  1461. <ul><ul>
  1462. <table>
  1463. <tr>
  1464. <td>
  1465. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterDayLast</code> : </li></td><td>Der letzte Z&auml;hlerstand des vorherigen Tages.<BR>
  1466. </td></tr>
  1467. </td>
  1468. </tr>
  1469. </table>
  1470. </ul></ul>
  1471. <ul><ul>
  1472. <table>
  1473. <tr>
  1474. <td>
  1475. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterMeter1st</code> : </li></td><td>Der erste Z&auml;hlerstand seit Mitternacht des ersten Tages der laufenden Ableseperiode.<BR>
  1476. </td></tr>
  1477. </td>
  1478. </tr>
  1479. </table>
  1480. </ul></ul>
  1481. <ul><ul>
  1482. <table>
  1483. <tr>
  1484. <td>
  1485. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterMeterLast</code> : </li></td><td>Der letzte Z&auml;hlerstand seit Mitternacht des ersten Tages der vorherigen Ableseperiode.<BR>
  1486. </td></tr>
  1487. </td>
  1488. </tr>
  1489. </table>
  1490. </ul></ul>
  1491. <ul><ul>
  1492. <table>
  1493. <tr>
  1494. <td>
  1495. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterMonth1st</code> : </li></td><td>Der erste Z&auml;hlerstand seit Mitternacht des ersten Tages des laufenden Monats.<BR>
  1496. </td></tr>
  1497. </td>
  1498. </tr>
  1499. </table>
  1500. </ul></ul>
  1501. <ul><ul>
  1502. <table>
  1503. <tr>
  1504. <td>
  1505. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterMonthLast</code> : </li></td><td>Der letzte Z&auml;hlerstand des vorherigen Monats.<BR>
  1506. </td></tr>
  1507. </td>
  1508. </tr>
  1509. </table>
  1510. </ul></ul>
  1511. <ul><ul>
  1512. <table>
  1513. <tr>
  1514. <td>
  1515. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterYear1st</code> : </li></td><td>Der erste Z&auml;hlerstand seit Mitternacht des ersten Tages des laufenden Jahres.<BR>
  1516. </td></tr>
  1517. </td>
  1518. </tr>
  1519. </table>
  1520. </ul></ul>
  1521. <ul><ul>
  1522. <table>
  1523. <tr>
  1524. <td>
  1525. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_CounterYearLast</code> : </li></td><td>Der letzte Z&auml;hlerstand des letzten Jahres.<BR>
  1526. </td></tr>
  1527. </td>
  1528. </tr>
  1529. </table>
  1530. </ul></ul>
  1531. <ul><ul>
  1532. <table>
  1533. <tr>
  1534. <td>
  1535. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionCostDayLast</code> : </li></td><td>Wasserkosten des letzten Tages.<BR>
  1536. </td></tr>
  1537. </td>
  1538. </tr>
  1539. </table>
  1540. </ul></ul>
  1541. <ul><ul>
  1542. <table>
  1543. <tr>
  1544. <td>
  1545. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionCostMeterLast</code> : </li></td><td>Wasserkosten der letzten Ableseperiode.<BR>
  1546. </td></tr>
  1547. </td>
  1548. </tr>
  1549. </table>
  1550. </ul></ul>
  1551. <ul><ul>
  1552. <table>
  1553. <tr>
  1554. <td>
  1555. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionCostMonthLast</code> : </li></td><td>Wasserkosten des letzten Monats.<BR>
  1556. </td></tr>
  1557. </td>
  1558. </tr>
  1559. </table>
  1560. </ul></ul>
  1561. <ul><ul>
  1562. <table>
  1563. <tr>
  1564. <td>
  1565. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionCostYearLast</code> : </li></td><td>Wasserkosten des letzten Kalenderjahres.<BR>
  1566. </td></tr>
  1567. </td>
  1568. </tr>
  1569. </table>
  1570. </ul></ul>
  1571. <ul><ul>
  1572. <table>
  1573. <tr>
  1574. <td>
  1575. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionCostDay</code> : </li></td><td>Wasserkosten in gew&auml;hlter W&auml;hrung seit Mitternacht des laufenden Tages.<BR>
  1576. </td></tr>
  1577. </td>
  1578. </tr>
  1579. </table>
  1580. </ul></ul>
  1581. <ul><ul>
  1582. <table>
  1583. <tr>
  1584. <td>
  1585. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionCostMeter</code> : </li></td><td>Wasserkosten in gew&auml;hlter W&auml;hrung seit Beginn der laufenden Ableseperiode.<BR>
  1586. </td></tr>
  1587. </td>
  1588. </tr>
  1589. </table>
  1590. </ul></ul>
  1591. <ul><ul>
  1592. <table>
  1593. <tr>
  1594. <td>
  1595. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionCostMonth</code> : </li></td><td>Wasserkosten in gew&auml;hlter W&auml;hrung seit Beginn des laufenden Monats.<BR>
  1596. </td></tr>
  1597. </td>
  1598. </tr>
  1599. </table>
  1600. </ul></ul>
  1601. <ul><ul>
  1602. <table>
  1603. <tr>
  1604. <td>
  1605. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionCostYear</code> : </li></td><td>Wasserkosten in gew&auml;hlter W&auml;hrung seit Beginn des laufenden Kalenderjahres.<BR>
  1606. </td></tr>
  1607. </td>
  1608. </tr>
  1609. </table>
  1610. </ul></ul>
  1611. <ul><ul>
  1612. <table>
  1613. <tr>
  1614. <td>
  1615. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionDay</code> : </li></td><td>Wasserverbrauch seit Beginn der aktuellen Tages (Mitternacht).<BR>
  1616. </td></tr>
  1617. </td>
  1618. </tr>
  1619. </table>
  1620. </ul></ul>
  1621. <ul><ul>
  1622. <table>
  1623. <tr>
  1624. <td>
  1625. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionDayLast</code> : </li></td><td>Wasserverbrauch in qm des vorherigen Tages.<BR>
  1626. </td></tr>
  1627. </td>
  1628. </tr>
  1629. </table>
  1630. </ul></ul>
  1631. <ul><ul>
  1632. <table>
  1633. <tr>
  1634. <td>
  1635. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionMeter</code> : </li></td><td>Wasserverbrauch seit Beginn der aktuellen Ableseperiode.<BR>
  1636. </td></tr>
  1637. </td>
  1638. </tr>
  1639. </table>
  1640. </ul></ul>
  1641. <ul><ul>
  1642. <table>
  1643. <tr>
  1644. <td>
  1645. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionMeterLast</code> : </li></td><td>Wasserverbrauch in qm der vorherigen Ableseperiode.<BR>
  1646. </td></tr>
  1647. </td>
  1648. </tr>
  1649. </table>
  1650. </ul></ul>
  1651. <ul><ul>
  1652. <table>
  1653. <tr>
  1654. <td>
  1655. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionMonth</code> : </li></td><td>Wasserverbrauch seit Beginn des aktuellen Monats.<BR>
  1656. </td></tr>
  1657. </td>
  1658. </tr>
  1659. </table>
  1660. </ul></ul>
  1661. <ul><ul>
  1662. <table>
  1663. <tr>
  1664. <td>
  1665. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionMonthLast</code> : </li></td><td>Wasserverbrauch in qm des vorherigen Monats.<BR>
  1666. </td></tr>
  1667. </td>
  1668. </tr>
  1669. </table>
  1670. </ul></ul>
  1671. <ul><ul>
  1672. <table>
  1673. <tr>
  1674. <td>
  1675. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionYear</code> : </li></td><td>Wasserverbrauch seit Beginn des aktuellen Kalenderjahres.<BR>
  1676. </td></tr>
  1677. </td>
  1678. </tr>
  1679. </table>
  1680. </ul></ul>
  1681. <ul><ul>
  1682. <table>
  1683. <tr>
  1684. <td>
  1685. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_ConsumptionYearLast</code> : </li></td><td>Wasserverbrauch in qm des vorherigen Kalenderjahres.<BR>
  1686. </td></tr>
  1687. </td>
  1688. </tr>
  1689. </table>
  1690. </ul></ul>
  1691. <ul><ul>
  1692. <table>
  1693. <tr>
  1694. <td>
  1695. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_FinanceReserve</code> : </li></td><td>Finanzielle Reserve basierend auf den Abschlagszahlungen die jeden Monat an den Wasserversorger gezahlt werden. Bei negativen Werten ist von einer Nachzahlung auszugehen.<BR>
  1696. </td></tr>
  1697. </td>
  1698. </tr>
  1699. </table>
  1700. </ul></ul>
  1701. <ul><ul>
  1702. <table>
  1703. <tr>
  1704. <td>
  1705. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_MonthMeterReading</code> : </li></td><td>Anzahl der Monate seit der letzten Zählerablesung. Der Monat der Zählerablesung ist der erste Monat = 1.<BR>
  1706. </td></tr>
  1707. </td>
  1708. </tr>
  1709. </table>
  1710. </ul></ul>
  1711. <ul><ul>
  1712. <table>
  1713. <tr>
  1714. <td>
  1715. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_WFRCurrent</code> : </li></td><td>Aktueller Wasserdurchsatz. (Wasserdurchsatz basierend auf aktueller und letzter Messung)<BR>
  1716. </td></tr>
  1717. </td>
  1718. </tr>
  1719. </table>
  1720. </ul></ul>
  1721. <ul><ul>
  1722. <table>
  1723. <tr>
  1724. <td>
  1725. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_WFRDayAver</code> : </li></td><td>Mittlerer Wasserdurchsatz seit Mitternacht.<BR>
  1726. </td></tr>
  1727. </td>
  1728. </tr>
  1729. </table>
  1730. </ul></ul>
  1731. <ul><ul>
  1732. <table>
  1733. <tr>
  1734. <td>
  1735. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_WFRDayMax</code> : </li></td><td>Maximale Wasserdurchsatz seit Mitternacht.<BR>
  1736. </td></tr>
  1737. </td>
  1738. </tr>
  1739. </table>
  1740. </ul></ul>
  1741. <ul><ul>
  1742. <table>
  1743. <tr>
  1744. <td>
  1745. <tr><td><li><code>&lt;DestinationDevice&gt;_&lt;SourceCounterReading&gt;_WFRDayMin</code> : </li></td><td>Minimale Wasserdurchsatz seit Mitternacht.<BR>
  1746. </td></tr>
  1747. </td>
  1748. </tr>
  1749. </table>
  1750. </ul></ul>
  1751. </ul>
  1752. =end html_DE
  1753. =cut