74_GardenaSmartDevice.pm 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110
  1. ###############################################################################
  2. #
  3. # Developed with Kate
  4. #
  5. # (c) 2017-2018 Copyright: Marko Oldenburg (leongaultier at gmail dot com)
  6. # All rights reserved
  7. #
  8. # Special thanks goes to comitters:
  9. # - Michael (mbrak) Thanks for Commandref
  10. # - Matthias (Kenneth) Thanks for Wiki entry
  11. # - BioS Thanks for predefined start points Code
  12. # - fettgu Thanks for Debugging Irrigation Control data flow
  13. #
  14. #
  15. # This script is free software; you can redistribute it and/or modify
  16. # it under the terms of the GNU General Public License as published by
  17. # the Free Software Foundation; either version 2 of the License, or
  18. # any later version.
  19. #
  20. # The GNU General Public License can be found at
  21. # http://www.gnu.org/copyleft/gpl.html.
  22. # A copy is found in the textfile GPL.txt and important notices to the license
  23. # from the author is found in LICENSE.txt distributed with these scripts.
  24. #
  25. # This script is distributed in the hope that it will be useful,
  26. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  27. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  28. # GNU General Public License for more details.
  29. #
  30. #
  31. # $Id: 74_GardenaSmartDevice.pm 17536 2018-10-15 12:57:08Z CoolTux $
  32. #
  33. ###############################################################################
  34. ##
  35. ##
  36. ## Das JSON Modul immer in einem eval aufrufen
  37. # $data = eval{decode_json($data)};
  38. #
  39. # if($@){
  40. # Log3($SELF, 2, "$TYPE ($SELF) - error while request: $@");
  41. #
  42. # readingsSingleUpdate($hash, "state", "error", 1);
  43. #
  44. # return;
  45. # }
  46. #
  47. #
  48. ###### Wichtige Notizen
  49. #
  50. # apt-get install libio-socket-ssl-perl
  51. # http://www.dxsdata.com/de/2016/07/php-class-for-gardena-smart-system-api/
  52. #
  53. ##
  54. ##
  55. package main;
  56. use strict;
  57. use warnings;
  58. # # Declare functions
  59. # sub GardenaSmartDevice_Attr(@);
  60. # sub GardenaSmartDevice_Define($$);
  61. # sub GardenaSmartDevice_Initialize($);
  62. # sub GardenaSmartDevice_Set($@);
  63. # sub GardenaSmartDevice_Undef($$);
  64. # sub GardenaSmartDevice_WriteReadings($$);
  65. # sub GardenaSmartDevice_Parse($$);
  66. # sub GardenaSmartDevice_ReadingLangGerman($$);
  67. # sub GardenaSmartDevice_RigRadingsValue($$);
  68. # sub GardenaSmartDevice_Zulu2LocalString($);
  69. # sub GardenaSmartDevice_SetPredefinedStartPoints($@);
  70. my $version = "1.4.0";
  71. sub GardenaSmartDevice_Initialize($) {
  72. my ($hash) = @_;
  73. $hash->{Match} = '^{"id":".*';
  74. $hash->{SetFn} = "GardenaSmartDevice::Set";
  75. $hash->{DefFn} = "GardenaSmartDevice::Define";
  76. $hash->{UndefFn} = "GardenaSmartDevice::Undef";
  77. $hash->{ParseFn} = "GardenaSmartDevice::Parse";
  78. $hash->{AttrFn} = "GardenaSmartDevice::Attr";
  79. $hash->{AttrList} =
  80. "readingValueLanguage:de,en "
  81. . "model:watering_computer,sensor,mower,ic24 "
  82. . "IODev "
  83. . $readingFnAttributes;
  84. foreach my $d ( sort keys %{ $modules{GardenaSmartDevice}{defptr} } ) {
  85. my $hash = $modules{GardenaSmartDevice}{defptr}{$d};
  86. $hash->{VERSION} = $version;
  87. }
  88. }
  89. ## unserer packagename
  90. package GardenaSmartDevice;
  91. use GPUtils qw(:all)
  92. ; # wird für den Import der FHEM Funktionen aus der fhem.pl benötigt
  93. my $missingModul = "";
  94. use strict;
  95. use warnings;
  96. use POSIX;
  97. use Time::Local;
  98. eval "use JSON;1" or $missingModul .= "JSON ";
  99. ## Import der FHEM Funktionen
  100. BEGIN {
  101. GP_Import(
  102. qw(readingsSingleUpdate
  103. readingsBulkUpdate
  104. readingsBulkUpdateIfChanged
  105. readingsBeginUpdate
  106. readingsEndUpdate
  107. Log3
  108. CommandAttr
  109. AttrVal
  110. ReadingsVal
  111. AssignIoPort
  112. modules
  113. IOWrite
  114. defs)
  115. );
  116. }
  117. sub Define($$) {
  118. my ( $hash, $def ) = @_;
  119. my @a = split( "[ \t]+", $def );
  120. return
  121. "too few parameters: define <NAME> GardenaSmartDevice <device_Id> <model>"
  122. if ( @a < 3 );
  123. return
  124. "Cannot define Gardena Bridge device. Perl modul $missingModul is missing."
  125. if ($missingModul);
  126. my $name = $a[0];
  127. my $deviceId = $a[2];
  128. my $category = $a[3];
  129. $hash->{DEVICEID} = $deviceId;
  130. $hash->{VERSION} = $version;
  131. $hash->{helper}{STARTINGPOINTID} = '';
  132. CommandAttr( undef,
  133. "$name IODev $modules{GardenaSmartBridge}{defptr}{BRIDGE}->{NAME}" )
  134. if ( AttrVal( $name, 'IODev', 'none' ) eq 'none' );
  135. my $iodev = AttrVal( $name, 'IODev', 'none' );
  136. AssignIoPort( $hash, $iodev ) if ( !$hash->{IODev} );
  137. if ( defined( $hash->{IODev}->{NAME} ) ) {
  138. Log3 $name, 3, "GardenaSmartDevice ($name) - I/O device is "
  139. . $hash->{IODev}->{NAME};
  140. }
  141. else {
  142. Log3 $name, 1, "GardenaSmartDevice ($name) - no I/O device";
  143. }
  144. $iodev = $hash->{IODev}->{NAME};
  145. my $d = $modules{GardenaSmartDevice}{defptr}{$deviceId};
  146. return
  147. "GardenaSmartDevice device $name on GardenaSmartBridge $iodev already defined."
  148. if ( defined($d)
  149. and $d->{IODev} == $hash->{IODev}
  150. and $d->{NAME} ne $name );
  151. #$attr{$name}{room} = "GardenaSmart" if( not defined( $attr{$name}{room} ) );
  152. CommandAttr( undef, $name . ' room GardenaSmart' )
  153. if ( AttrVal( $name, 'room', 'none' ) eq 'none' );
  154. #$attr{$name}{model} = $category if( not defined( $attr{$name}{model} ) );
  155. CommandAttr( undef, $name . ' model ' . $category )
  156. if ( AttrVal( $name, 'model', 'none' ) eq 'none' );
  157. Log3 $name, 3,
  158. "GardenaSmartDevice ($name) - defined GardenaSmartDevice with DEVICEID: $deviceId";
  159. readingsSingleUpdate( $hash, 'state', 'initialized', 1 );
  160. $modules{GardenaSmartDevice}{defptr}{$deviceId} = $hash;
  161. return undef;
  162. }
  163. sub Undef($$) {
  164. my ( $hash, $arg ) = @_;
  165. my $name = $hash->{NAME};
  166. my $deviceId = $hash->{DEVICEID};
  167. delete $modules{GardenaSmartDevice}{defptr}{$deviceId};
  168. return undef;
  169. }
  170. sub Attr(@) {
  171. my ( $cmd, $name, $attrName, $attrVal ) = @_;
  172. my $hash = $defs{$name};
  173. return undef;
  174. }
  175. sub Set($@) {
  176. my ( $hash, $name, $cmd, @args ) = @_;
  177. #my ($arg, @params) = @args;
  178. my $payload;
  179. my $abilities = '';
  180. ### mower
  181. if ( lc $cmd eq 'parkuntilfurthernotice' ) {
  182. $payload = '"name":"park_until_further_notice"';
  183. }
  184. elsif ( lc $cmd eq 'parkuntilnexttimer' ) {
  185. $payload = '"name":"park_until_next_timer"';
  186. }
  187. elsif ( lc $cmd eq 'startresumeschedule' ) {
  188. $payload = '"name":"start_resume_schedule"';
  189. }
  190. elsif ( lc $cmd eq 'startoverridetimer' ) {
  191. my $duration = join( " ", @args );
  192. $payload = '"name":"start_override_timer","parameters":{"duration":'
  193. . $duration . '}';
  194. }
  195. elsif ( lc $cmd eq 'startpoint' ) {
  196. my $err;
  197. ( $err, $payload, $abilities ) =
  198. SetPredefinedStartPoints( $hash, @args );
  199. return $err if ( defined($err) );
  200. ### watering_computer
  201. }
  202. elsif ( lc $cmd eq 'manualoverride' ) {
  203. my $duration = join( " ", @args );
  204. $payload = '"name":"manual_override","parameters":{"duration":'
  205. . $duration . '}';
  206. }
  207. elsif ( lc $cmd eq 'canceloverride' ) {
  208. $payload = '"name":"cancel_override"';
  209. ### Watering ic24
  210. }
  211. elsif ( $cmd =~ /manualDurationValve/ ) {
  212. my $valve_id;
  213. my $duration = join( " ", @args );
  214. if ( $cmd =~ m#(\d)$# ) {
  215. $valve_id = $1;
  216. }
  217. $payload =
  218. '"properties":{"name":"watering_timer_'
  219. . $valve_id
  220. . '","value":{"state":"manual","duration":'
  221. . $duration
  222. . ',"valve_id":'
  223. . $valve_id . '}}';
  224. ### Sensors
  225. }
  226. elsif ( lc $cmd eq 'refresh' ) {
  227. my $sensname = join( " ", @args );
  228. if ( lc $sensname eq 'temperature' ) {
  229. $payload = '"name":"measure_ambient_temperature"';
  230. $abilities = 'ambient_temperature';
  231. }
  232. elsif ( lc $sensname eq 'light' ) {
  233. $payload = '"name":"measure_light"';
  234. $abilities = 'light';
  235. }
  236. elsif ( lc $sensname eq 'humidity' ) {
  237. $payload = '"name":"measure_soil_humidity"';
  238. $abilities = 'humidity';
  239. }
  240. }
  241. else {
  242. my $list = '';
  243. $list .=
  244. 'parkUntilFurtherNotice:noArg parkUntilNextTimer:noArg startResumeSchedule:noArg startOverrideTimer:slider,0,60,1440 startpoint'
  245. if ( AttrVal( $name, 'model', 'unknown' ) eq 'mower' );
  246. $list .= 'manualOverride:slider,0,1,59 cancelOverride:noArg'
  247. if ( AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer' );
  248. $list .=
  249. 'manualDurationValve1:slider,1,1,59 manualDurationValve2:slider,1,1,59 manualDurationValve3:slider,1,1,59 manualDurationValve4:slider,1,1,59 manualDurationValve5:slider,1,1,59 manualDurationValve6:slider,1,1,59'
  250. if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' );
  251. $list .= 'refresh:temperature,light,humidity'
  252. if ( AttrVal( $name, 'model', 'unknown' ) eq 'sensor' );
  253. return "Unknown argument $cmd, choose one of $list";
  254. }
  255. $abilities = 'mower'
  256. if ( AttrVal( $name, 'model', 'unknown' ) eq 'mower' )
  257. and $abilities ne 'mower_settings';
  258. $abilities = 'outlet'
  259. if ( AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer' );
  260. $abilities = 'watering'
  261. if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' );
  262. $hash->{helper}{deviceAction} = $payload;
  263. readingsSingleUpdate( $hash, "state", "send command to gardena cloud", 1 );
  264. IOWrite( $hash, $payload, $hash->{DEVICEID}, $abilities );
  265. Log3 $name, 4,
  266. "GardenaSmartBridge ($name) - IOWrite: $payload $hash->{DEVICEID} $abilities IODevHash=$hash->{IODev}";
  267. return undef;
  268. }
  269. sub Parse($$) {
  270. my ( $io_hash, $json ) = @_;
  271. my $name = $io_hash->{NAME};
  272. my $decode_json = eval { decode_json($json) };
  273. if ($@) {
  274. Log3 $name, 3,
  275. "GardenaSmartBridge ($name) - JSON error while request: $@";
  276. }
  277. Log3 $name, 4, "GardenaSmartDevice ($name) - ParseFn was called";
  278. Log3 $name, 4, "GardenaSmartDevice ($name) - JSON: $json";
  279. if ( defined( $decode_json->{id} ) ) {
  280. my $deviceId = $decode_json->{id};
  281. if ( my $hash = $modules{GardenaSmartDevice}{defptr}{$deviceId} ) {
  282. my $name = $hash->{NAME};
  283. WriteReadings( $hash, $decode_json );
  284. Log3 $name, 4,
  285. "GardenaSmartDevice ($name) - find logical device: $hash->{NAME}";
  286. return $hash->{NAME};
  287. }
  288. else {
  289. Log3 $name, 3,
  290. "GardenaSmartDevice ($name) - autocreate new device "
  291. . makeDeviceName( $decode_json->{name} )
  292. . " with deviceId $decode_json->{id}, model $decode_json->{category}";
  293. return
  294. "UNDEFINED "
  295. . makeDeviceName( $decode_json->{name} )
  296. . " GardenaSmartDevice $decode_json->{id} $decode_json->{category}";
  297. }
  298. }
  299. }
  300. sub WriteReadings($$) {
  301. my ( $hash, $decode_json ) = @_;
  302. my $name = $hash->{NAME};
  303. my $abilities = scalar( @{ $decode_json->{abilities} } );
  304. my $settings = scalar( @{ $decode_json->{settings} } );
  305. readingsBeginUpdate($hash);
  306. do {
  307. if (
  308. ref( $decode_json->{abilities}[$abilities]{properties} ) eq "ARRAY"
  309. and
  310. scalar( @{ $decode_json->{abilities}[$abilities]{properties} } ) >
  311. 0 )
  312. {
  313. foreach my $propertie (
  314. @{ $decode_json->{abilities}[$abilities]{properties} } )
  315. {
  316. readingsBulkUpdateIfChanged(
  317. $hash,
  318. $decode_json->{abilities}[$abilities]{name} . '-'
  319. . $propertie->{name},
  320. RigRadingsValue(
  321. $hash, $propertie->{value}
  322. )
  323. )
  324. if ( defined( $propertie->{value} )
  325. and $decode_json->{abilities}[$abilities]{name} . '-'
  326. . $propertie->{name} ne 'radio-quality'
  327. and $decode_json->{abilities}[$abilities]{name} . '-'
  328. . $propertie->{name} ne 'battery-level'
  329. and $decode_json->{abilities}[$abilities]{name} . '-'
  330. . $propertie->{name} ne 'internal_temperature-temperature'
  331. and $decode_json->{abilities}[$abilities]{name} . '-'
  332. . $propertie->{name} ne 'ambient_temperature-temperature'
  333. and $decode_json->{abilities}[$abilities]{name} . '-'
  334. . $propertie->{name} ne 'soil_temperature-temperature'
  335. and $decode_json->{abilities}[$abilities]{name} . '-'
  336. . $propertie->{name} ne 'humidity-humidity'
  337. and $decode_json->{abilities}[$abilities]{name} . '-'
  338. . $propertie->{name} ne 'light-light'
  339. and ref( $propertie->{value} ) ne "HASH" );
  340. readingsBulkUpdate(
  341. $hash,
  342. $decode_json->{abilities}[$abilities]{name} . '-'
  343. . $propertie->{name},
  344. RigRadingsValue(
  345. $hash, $propertie->{value}
  346. )
  347. )
  348. if (
  349. defined( $propertie->{value} )
  350. and ( $decode_json->{abilities}[$abilities]{name} . '-'
  351. . $propertie->{name} eq 'radio-quality'
  352. or $decode_json->{abilities}[$abilities]{name} . '-'
  353. . $propertie->{name} eq 'battery-level'
  354. or $decode_json->{abilities}[$abilities]{name} . '-'
  355. . $propertie->{name} eq
  356. 'internal_temperature-temperature'
  357. or $decode_json->{abilities}[$abilities]{name} . '-'
  358. . $propertie->{name} eq
  359. 'ambient_temperature-temperature'
  360. or $decode_json->{abilities}[$abilities]{name} . '-'
  361. . $propertie->{name} eq 'soil_temperature-temperature'
  362. or $decode_json->{abilities}[$abilities]{name} . '-'
  363. . $propertie->{name} eq 'humidity-humidity'
  364. or $decode_json->{abilities}[$abilities]{name} . '-'
  365. . $propertie->{name} eq 'light-light' )
  366. );
  367. readingsBulkUpdateIfChanged(
  368. $hash,
  369. $decode_json->{abilities}[$abilities]{name} . '-'
  370. . $propertie->{name},
  371. join( ',', @{ $propertie->{value} } )
  372. )
  373. if ( defined( $propertie->{value} )
  374. and $decode_json->{abilities}[$abilities]{name} . '-'
  375. . $propertie->{name} eq 'ic24-valves_connected' );
  376. readingsBulkUpdateIfChanged(
  377. $hash,
  378. $decode_json->{abilities}[$abilities]{name} . '-'
  379. . $propertie->{name},
  380. join( ',', @{ $propertie->{value} } )
  381. )
  382. if ( defined( $propertie->{value} )
  383. and $decode_json->{abilities}[$abilities]{name} . '-'
  384. . $propertie->{name} eq 'ic24-valves_master_config' );
  385. if ( ref( $propertie->{value} ) eq "HASH" ) {
  386. while ( my ( $r, $v ) = each %{ $propertie->{value} } ) {
  387. readingsBulkUpdate(
  388. $hash,
  389. $decode_json->{abilities}[$abilities]{name} . '-'
  390. . $propertie->{name} . '_'
  391. . $r,
  392. RigRadingsValue( $hash, $v )
  393. );
  394. }
  395. }
  396. }
  397. }
  398. $abilities--;
  399. } while ( $abilities >= 0 );
  400. do {
  401. if ( ref( $decode_json->{settings}[$settings]{value} ) eq "ARRAY"
  402. and $decode_json->{settings}[$settings]{name} eq 'starting_points' )
  403. {
  404. #save the startingpointid needed to update the startingpoints
  405. if ( $hash->{helper}{STARTINGPOINTID} ne
  406. $decode_json->{settings}[$settings]{id} )
  407. {
  408. $hash->{helper}{STARTINGPOINTID} =
  409. $decode_json->{settings}[$settings]{id};
  410. }
  411. $hash->{helper}{STARTINGPOINTS} =
  412. '{ "name": "starting_points", "value": '
  413. . encode_json( $decode_json->{settings}[$settings]{value} ) . '}';
  414. my $startpoint_cnt = 0;
  415. foreach my $startingpoint (
  416. @{ $decode_json->{settings}[$settings]{value} } )
  417. {
  418. $startpoint_cnt++;
  419. readingsBulkUpdateIfChanged(
  420. $hash,
  421. 'startpoint-' . $startpoint_cnt . '-enabled',
  422. $startingpoint->{enabled}
  423. );
  424. }
  425. }
  426. $settings--;
  427. } while ( $settings >= 0 );
  428. readingsBulkUpdate( $hash, 'state',
  429. ReadingsVal( $name, 'mower-status', 'readingsValError' ) )
  430. if ( AttrVal( $name, 'model', 'unknown' ) eq 'mower' );
  431. readingsBulkUpdate(
  432. $hash, 'state',
  433. (
  434. ReadingsVal( $name, 'outlet-valve_open', 'readingsValError' ) == 1
  435. ? RigRadingsValue( $hash, 'open' )
  436. : RigRadingsValue( $hash, 'closed' )
  437. )
  438. ) if ( AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer' );
  439. readingsBulkUpdate(
  440. $hash, 'state',
  441. 'T: '
  442. . ReadingsVal( $name, 'ambient_temperature-temperature',
  443. 'readingsValError' )
  444. . '°C, H: '
  445. . ReadingsVal( $name, 'humidity-humidity', 'readingsValError' )
  446. . '%, L: '
  447. . ReadingsVal( $name, 'light-light', 'readingsValError' ) . 'lux'
  448. ) if ( AttrVal( $name, 'model', 'unknown' ) eq 'sensor' );
  449. readingsBulkUpdate(
  450. $hash, 'state',
  451. 'scheduled watering next start: '
  452. . (
  453. ReadingsVal(
  454. $name, 'scheduling-scheduled_watering_next_start',
  455. 'readingsValError'
  456. )
  457. )
  458. ) if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' );
  459. readingsEndUpdate( $hash, 1 );
  460. Log3 $name, 4, "GardenaSmartDevice ($name) - readings was written}";
  461. }
  462. ##################################
  463. ##################################
  464. #### my little helpers ###########
  465. sub ReadingLangGerman($$) {
  466. my ( $hash, $readingValue ) = @_;
  467. my $name = $hash->{NAME};
  468. my %langGermanMapp = (
  469. 'ok_cutting' => 'mähen',
  470. 'paused' => 'pausiert',
  471. 'ok_searching' => 'suche Ladestation',
  472. 'ok_charging' => 'lädt',
  473. 'ok_leaving' => 'mähen',
  474. 'wait_updating' => 'wird aktualisiert ...',
  475. 'wait_power_up' => 'wird eingeschaltet ...',
  476. 'parked_timer' => 'geparkt nach Zeitplan',
  477. 'parked_park_selected' => 'geparkt',
  478. 'off_disabled' => 'der Mäher ist ausgeschaltet',
  479. 'off_hatch_open' =>
  480. 'deaktiviert. Abdeckung ist offen oder PIN-Code erforderlich',
  481. 'unknown' => 'unbekannter Status',
  482. 'error' => 'Fehler',
  483. 'error_at_power_up' => 'Neustart ...',
  484. 'off_hatch_closed' => 'Deaktiviert. Manueller Start erforderlich',
  485. 'ok_cutting_timer_overridden' => 'manuelles mähen',
  486. 'parked_autotimer' => 'geparkt durch SensorControl',
  487. 'parked_daily_limit_reached' => 'abgeschlossen',
  488. 'no_message' => 'kein Fehler',
  489. 'outside_working_area' => 'außerhalb des Arbeitsbereichs',
  490. 'no_loop_signal' => 'kein Schleifensignal',
  491. 'wrong_loop_signal' => 'falsches Schleifensignal',
  492. 'loop_sensor_problem_front' => 'Problem Schleifensensor, vorne',
  493. 'loop_sensor_problem_rear' => 'Problem Schleifensensor, hinten',
  494. 'trapped' => 'eingeschlossen',
  495. 'upside_down' => 'steht auf dem Kopf',
  496. 'low_battery' => 'niedriger Batteriestand',
  497. 'empty_battery' => 'Batterie leer',
  498. 'no_drive' => 'fährt nicht',
  499. 'lifted' => 'angehoben',
  500. 'stuck_in_charging_station' => 'eingeklemmt in Ladestation',
  501. 'charging_station_blocked' => 'Ladestation blockiert',
  502. 'collision_sensor_problem_rear' => 'Problem Stoßsensor hinten',
  503. 'collision_sensor_problem_front' => 'Problem Stoßsensor vorne',
  504. 'wheel_motor_blocked_right' => 'Radmotor rechts blockiert',
  505. 'wheel_motor_blocked_left' => 'Radmotor links blockiert',
  506. 'wheel_drive_problem_right' => 'Problem Antrieb, rechts',
  507. 'wheel_drive_problem_left' => 'Problem Antrieb, links',
  508. 'cutting_system_blocked' => 'Schneidsystem blockiert',
  509. 'invalid_sub_device_combination' => 'fehlerhafte Verbindung',
  510. 'settings_restored' => 'Standardeinstellungen',
  511. 'electronic_problem' => 'elektronisches Problem',
  512. 'charging_system_problem' => 'Problem Ladesystem',
  513. 'tilt_sensor_problem' => 'Kippsensor Problem',
  514. 'wheel_motor_overloaded_right' => 'rechter Radmotor überlastet',
  515. 'wheel_motor_overloaded_left' => 'linker Radmotor überlastet',
  516. 'charging_current_too_high' => 'Ladestrom zu hoch',
  517. 'temporary_problem' => 'vorübergehendes Problem',
  518. 'guide_1_not_found' => 'SK 1 nicht gefunden',
  519. 'guide_2_not_found' => 'SK 2 nicht gefunden',
  520. 'guide_3_not_found' => 'SK 3 nicht gefunden',
  521. 'difficult_finding_home' => 'Problem die Ladestation zu finden',
  522. 'guide_calibration_accomplished' =>
  523. 'Kalibrierung des Suchkabels beendet',
  524. 'guide_calibration_failed' =>
  525. 'Kalibrierung des Suchkabels fehlgeschlagen',
  526. 'temporary_battery_problem' => 'kurzzeitiges Batterieproblem',
  527. 'battery_problem' => 'Batterieproblem',
  528. 'alarm_mower_switched_off' => 'Alarm! Mäher ausgeschalten',
  529. 'alarm_mower_stopped' => 'Alarm! Mäher gestoppt',
  530. 'alarm_mower_lifted' => 'Alarm! Mäher angehoben',
  531. 'alarm_mower_tilted' => 'Alarm! Mäher gekippt',
  532. 'connection_changed' => 'Verbindung geändert',
  533. 'connection_not_changed' => 'Verbindung nicht geändert',
  534. 'com_board_not_available' => 'COM Board nicht verfügbar',
  535. 'slipped' => 'rutscht',
  536. 'out_of_operation' => 'ausser Betrieb',
  537. 'replace_now' => 'kritischer Batteriestand, wechseln Sie jetzt',
  538. 'low' => 'niedrig',
  539. 'ok' => 'ok',
  540. 'no_source' => 'ok',
  541. 'mower_charging' => 'Mäher wurde geladen',
  542. 'completed_cutting_autotimer' => 'Sensor Control erreicht',
  543. 'week_timer' => 'Wochentimer erreicht',
  544. 'countdown_timer' => 'Stoppuhr Timer',
  545. 'undefined' => 'unklar',
  546. 'unknown' => 'unklar',
  547. 'status_device_unreachable' => 'Gerät ist nicht in Reichweite',
  548. 'status_device_alive' => 'Gerät ist in Reichweite',
  549. 'bad' => 'schlecht',
  550. 'poor' => 'schwach',
  551. 'good' => 'gut',
  552. 'undefined' => 'unklar',
  553. 'idle' => 'nichts zu tun',
  554. 'firmware_cancel' => 'Firmwareupload unterbrochen',
  555. 'firmware_upload' => 'Firmwareupload',
  556. 'unsupported' => 'nicht unterstützt',
  557. 'up_to_date' => 'auf dem neusten Stand',
  558. 'mower' => 'Mäher',
  559. 'watering_computer' => 'Bewässerungscomputer',
  560. 'no_frost' => 'kein Frost',
  561. 'open' => 'offen',
  562. 'closed' => 'geschlossen',
  563. 'included' => 'inbegriffen',
  564. 'active' => 'aktiv',
  565. 'inactive' => 'nicht aktiv'
  566. );
  567. if (
  568. defined( $langGermanMapp{$readingValue} )
  569. and ( AttrVal( 'global', 'language', 'none' ) eq 'DE'
  570. or AttrVal( $name, 'readingValueLanguage', 'none' ) eq 'de' )
  571. and AttrVal( $name, 'readingValueLanguage', 'none' ) ne 'en'
  572. )
  573. {
  574. return $langGermanMapp{$readingValue};
  575. }
  576. else {
  577. return $readingValue;
  578. }
  579. }
  580. sub RigRadingsValue($$) {
  581. my ( $hash, $readingValue ) = @_;
  582. my $rigReadingValue;
  583. if ( $readingValue =~ /^(\d+)-(\d\d)-(\d\d)T(\d\d)/ ) {
  584. $rigReadingValue = Zulu2LocalString($readingValue);
  585. }
  586. else {
  587. $rigReadingValue =
  588. ReadingLangGerman( $hash, $readingValue );
  589. }
  590. return $rigReadingValue;
  591. }
  592. sub Zulu2LocalString($) {
  593. my $t = shift;
  594. my ( $datehour, $datemin, $rest ) = split( /:/, $t, 3 );
  595. my ( $year, $month, $day, $hour, $min ) =
  596. $datehour =~ /(\d+)-(\d\d)-(\d\d)T(\d\d)/;
  597. my $epoch = timegm( 0, 0, $hour, $day, $month - 1, $year );
  598. my ( $lyear, $lmonth, $lday, $lhour, $isdst ) =
  599. ( localtime($epoch) )[ 5, 4, 3, 2, -1 ];
  600. $lyear += 1900; # year is 1900 based
  601. $lmonth++; # month number is zero based
  602. if ( defined($rest) ) {
  603. return (
  604. sprintf(
  605. "%04d-%02d-%02d %02d:%02d:%s",
  606. $lyear, $lmonth, $lday,
  607. $lhour, $datemin, substr( $rest, 0, 2 )
  608. )
  609. );
  610. }
  611. elsif ( $lyear < 2000 ) {
  612. return "illegal year";
  613. }
  614. else {
  615. return (
  616. sprintf(
  617. "%04d-%02d-%02d %02d:%02d",
  618. $lyear, $lmonth, $lday, $lhour, substr( $datemin, 0, 2 )
  619. )
  620. );
  621. }
  622. }
  623. sub SetPredefinedStartPoints($@) {
  624. my ( $hash, $startpoint_state, $startpoint_num, @morestartpoints ) = @_;
  625. my $name = $hash->{NAME};
  626. my $payload;
  627. my $abilities;
  628. if ( defined($startpoint_state) and defined($startpoint_num) ) {
  629. if ( defined( $hash->{helper}{STARTINGPOINTS} )
  630. and $hash->{helper}{STARTINGPOINTS} ne '' )
  631. {
  632. # add needed parameters to saved settings config and change the value in request
  633. my $decode_json_settings =
  634. eval { decode_json( $hash->{helper}{STARTINGPOINTS} ) };
  635. if ($@) {
  636. Log3 $name, 3,
  637. "GardenaSmartBridge ($name) - JSON error while setting startpoint: $@";
  638. }
  639. $decode_json_settings->{device} = $hash->{DEVICEID};
  640. my $setval = $startpoint_state eq 'disable' ? \0 : \1;
  641. $decode_json_settings->{value}[ $startpoint_num - 1 ]{enabled} =
  642. $setval;
  643. #set more startpoints
  644. if (
  645. defined scalar(@morestartpoints)
  646. and ( scalar(@morestartpoints) == 2
  647. or scalar(@morestartpoints) == 4 )
  648. )
  649. {
  650. if ( scalar(@morestartpoints) == 2 ) {
  651. $setval = $morestartpoints[0] eq 'disable' ? \0 : \1;
  652. $decode_json_settings->{value}[ $morestartpoints[1] - 1 ]
  653. {enabled} = $setval;
  654. }
  655. elsif ( scalar(@morestartpoints) == 4 ) {
  656. $setval = $morestartpoints[0] eq 'disable' ? \0 : \1;
  657. $decode_json_settings->{value}[ $morestartpoints[1] - 1 ]
  658. {enabled} = $setval;
  659. $setval = $morestartpoints[2] eq 'disable' ? \0 : \1;
  660. $decode_json_settings->{value}[ $morestartpoints[3] - 1 ]
  661. {enabled} = $setval;
  662. }
  663. }
  664. $payload = '"settings": ' . encode_json($decode_json_settings);
  665. $abilities = 'mower_settings';
  666. }
  667. else {
  668. return
  669. "startingpoints not loaded yet, please wait a couple of minutes",
  670. undef, undef;
  671. }
  672. }
  673. else {
  674. return
  675. "startpoint usage: set "
  676. . $hash->{NAME}
  677. . " startpoint disable 1 [enable 2] [disable 3]", undef, undef;
  678. }
  679. return undef, $payload, $abilities;
  680. }
  681. 1;
  682. =pod
  683. =item device
  684. =item summary Modul to control GardenaSmart Devices
  685. =item summary_DE Modul zur Steuerung von GardenaSmartger&aumlten
  686. =begin html
  687. <a name="GardenaSmartDevice"></a>
  688. <h3>GardenaSmartDevice</h3>
  689. <ul>
  690. In combination with GardenaSmartBridge this FHEM Module controls the GardenaSmart Device using the GardenaCloud
  691. <br><br>
  692. Once the Bridge device is created, the connected devices are automatically recognized and created in FHEM. <br>
  693. From now on the devices can be controlled and changes in the GardenaAPP are synchronized with the state and readings of the devices.
  694. <a name="GardenaSmartDevicereadings"></a>
  695. <br><br><br>
  696. <b>Readings</b>
  697. <ul>
  698. <li>battery-charging - Indicator if the Battery is charged (0/1) or with newer Firmware (false/true)</li>
  699. <li>battery-level - load percentage of the Battery</li>
  700. <li>battery-rechargeable_battery_status - healthyness of the battery (out_of_operation/replace_now/low/ok)</li>
  701. <li>device_info-category - category of device (mower/watering_computer)</li>
  702. <li>device_info-last_time_online - timestamp of last radio contact</li>
  703. <li>device_info-manufacturer - manufacturer</li>
  704. <li>device_info-product - product type</li>
  705. <li>device_info-serial_number - serial number</li>
  706. <li>device_info-sgtin - </li>
  707. <li>device_info-version - firmware version</li>
  708. <li>firmware-firmware_command - firmware command (idle/firmware_cancel/firmware_upload/unsupported)</li>
  709. <li>firmware-firmware_status - firmware status </li>
  710. <li>firmware-firmware_update_start - indicator when a firmwareupload is started</li>
  711. <li>firmware-firmware_upload_progress - progress indicator of firmware update</li>
  712. <li>firmware-inclusion_status - inclusion status</li>
  713. <li>internal_temperature-temperature - internal device temperature</li>
  714. <li>mower-error - actual error message
  715. <ul>
  716. <li>no_message</li>
  717. <li>outside_working_area</li>
  718. <li>no_loop_signal</li>
  719. <li>wrong_loop_signal</li>
  720. <li>loop_sensor_problem_front</li>
  721. <li>loop_sensor_problem_rear</li>
  722. <li>trapped</li>
  723. <li>upside_down</li>
  724. <li>low_battery</li>
  725. <li>empty_battery</li>
  726. <li>no_drive</li>
  727. <li>lifted</li>
  728. <li>stuck_in_charging_station</li>
  729. <li>charging_station_blocked</li>
  730. <li>collision_sensor_problem_rear</li>
  731. <li>collision_sensor_problem_front</li>
  732. <li>wheel_motor_blocked_right</li>
  733. <li>wheel_motor_blocked_left</li>
  734. <li>wheel_drive_problem_right</li>
  735. <li>wheel_drive_problem_left</li>
  736. <li>cutting_system_blocked</li>
  737. <li>invalid_sub_device_combination</li>
  738. <li>settings_restored</li>
  739. <li>electronic_problem</li>
  740. <li>charging_system_problem</li>
  741. <li>tilt_sensor_problem</li>
  742. <li>wheel_motor_overloaded_right</li>
  743. <li>wheel_motor_overloaded_left</li>
  744. <li>charging_current_too_high</li>
  745. <li>temporary_problem</li>
  746. <li>guide_1_not_found</li>
  747. <li>guide_2_not_found</li>
  748. <li>guide_3_not_found</li>
  749. <li>difficult_finding_home</li>
  750. <li>guide_calibration_accomplished</li>
  751. <li>guide_calibration_failed</li>
  752. <li>temporary_battery_problem</li>
  753. <li>battery_problem</li>
  754. <li>alarm_mower_switched_off</li>
  755. <li>alarm_mower_stopped</li>
  756. <li>alarm_mower_lifted</li>
  757. <li>alarm_mower_tilted</li>
  758. <li>connection_changed</li>
  759. <li>connection_not_changed</li>
  760. <li>com_board_not_available</li>
  761. <li>slipped</li>
  762. </ul>
  763. </li>
  764. <li>mower-manual_operation - (0/1) or with newer Firmware (false/true)</li>
  765. <li>mower-override_end_time - manual override end time</li>
  766. <li>mower-source_for_next_start - source for the next start
  767. <ul>
  768. <li>no_source</li>
  769. <li>mower_charging</li>
  770. <li>completed_cutting_autotimer</li>
  771. <li>week_timer</li>
  772. <li>countdown_timer</li>
  773. <li>undefined</li>
  774. </ul>
  775. </li>
  776. <li>mower-status - mower state (see state)</li>
  777. <li>mower-timestamp_next_start - timestamp of next scheduled start</li>
  778. <li>radio-connection_status - state of connection</li>
  779. <li>radio-quality - percentage of the radio quality</li>
  780. <li>radio-state - radio state (bad/poor/good/undefined)</li>
  781. <li>state - state of the mower
  782. <ul>
  783. <li>paused</li>
  784. <li>ok_cutting</li>
  785. <li>ok_searching</li>
  786. <li>ok_charging</li>
  787. <li>ok_leaving</li>
  788. <li>wait_updating</li>
  789. <li>wait_power_up</li>
  790. <li>parked_timer</li>
  791. <li>parked_park_selected</li>
  792. <li>off_disabled</li>
  793. <li>off_hatch_open</li>
  794. <li>unknown</li>
  795. <li>error</li>
  796. <li>error_at_power_up</li>
  797. <li>off_hatch_closed</li>
  798. <li>ok_cutting_timer_overridden</li>
  799. <li>parked_autotimer</li>
  800. <li>parked_daily_limit_reached</li>
  801. </ul>
  802. </li>
  803. </ul>
  804. <br><br>
  805. <a name="GardenaSmartDeviceattributes"></a>
  806. <b>Attributes</b>
  807. <ul>
  808. <li>readingValueLanguage - Change the Language of Readings (de,en/if not set the default is english and the global language is not set at german) </li>
  809. <li>model - </li>
  810. </ul>
  811. <br><br>
  812. <a name="GardenaSmartDeviceset"></a>
  813. <b>set</b>
  814. <ul>
  815. <li>parkUntilFurtherNotice</li>
  816. <li>parkUntilNextTimer</li>
  817. <li>startOverrideTimer - (in minutes, 60 = 1h, 1440 = 24h, 4320 = 72h)</li>
  818. <li>startResumeSchedule</li>
  819. <li>startpoint enable|disable 1|2|3 - enables or disables one or more predefined start points</li>
  820. <ul>
  821. <li>set NAME startpoint enable 1</li>
  822. <li>set NAME startpoint disable 3 enable 1</li>
  823. </ul>
  824. </ul>
  825. </ul>
  826. =end html
  827. =begin html_DE
  828. <a name="GardenaSmartDevice"></a>
  829. <h3>GardenaSmartDevice</h3>
  830. <ul>
  831. Zusammen mit dem Device GardenaSmartDevice stellt dieses FHEM Modul die Kommunikation zwischen der GardenaCloud und Fhem her.
  832. <br><br>
  833. Wenn das GardenaSmartBridge Device erzeugt wurde, werden verbundene Ger&auml;te automatisch erkannt und in Fhem angelegt.<br>
  834. Von nun an k&ouml;nnen die eingebundenen Ger&auml;te gesteuert werden. &Auml;nderungen in der APP werden mit den Readings und dem Status syncronisiert.
  835. <a name="GardenaSmartDevicereadings"></a>
  836. </ul>
  837. <br>
  838. <ul>
  839. <b>Readings</b>
  840. <ul>
  841. <li>battery-charging - Ladeindikator (0/1) oder mit neuerer Firmware (false/true)</li>
  842. <li>battery-level - Ladezustand der Batterie in Prozent</li>
  843. <li>battery-rechargeable_battery_status - Zustand der Batterie (Ausser Betrieb/Kritischer Batteriestand, wechseln Sie jetzt/Niedrig/oK)</li>
  844. <li>device_info-category - Eigenschaft des Ger&auml;tes (M&auml;her/Bew&auml;sserungscomputer/Bodensensor)</li>
  845. <li>device_info-last_time_online - Zeitpunkt der letzten Funk&uuml;bertragung</li>
  846. <li>device_info-manufacturer - Hersteller</li>
  847. <li>device_info-product - Produkttyp</li>
  848. <li>device_info-serial_number - Seriennummer</li>
  849. <li>device_info-sgtin - </li>
  850. <li>device_info-version - Firmware Version</li>
  851. <li>firmware-firmware_command - Firmware Kommando (Nichts zu tun/Firmwareupload unterbrochen/Firmwareupload/nicht unterst&uuml;tzt)</li>
  852. <li>firmware-firmware_status - Firmware Status </li>
  853. <li>firmware-firmware_update_start - Firmwareupdate (0/1) oder mit neuerer Firmware (false/true)</li>
  854. <li>firmware-firmware_upload_progress - Firmwareupdatestatus in Prozent</li>
  855. <li>firmware-inclusion_status - Einbindungsstatus</li>
  856. <li>internal_temperature-temperature - Interne Ger&auml;te Temperatur</li>
  857. <li>mower-error - Aktuelle Fehler Meldung
  858. <ul>
  859. <li>Kein Fehler</li>
  860. <li>Au&szlig;erhalb des Arbeitsbereichs</li>
  861. <li>Kein Schleifensignal</li>
  862. <li>Falsches Schleifensignal</li>
  863. <li>Problem Schleifensensor, vorne</li>
  864. <li>Problem Schleifensensor, hinten</li>
  865. <li>Eingeschlossen</li>
  866. <li>Steht auf dem Kopf</li>
  867. <li>Niedriger Batteriestand</li>
  868. <li>Batterie ist leer</li>
  869. <li>Kein Antrieb</li>
  870. <li>Angehoben</li>
  871. <li>Eingeklemmt in Ladestation</li>
  872. <li>Ladestation blockiert</li>
  873. <li>Problem Sto&szlig;sensor hinten</li>
  874. <li>Problem Sto&szlig;sensor vorne</li>
  875. <li>Radmotor rechts blockiert</li>
  876. <li>Radmotor links blockiert</li>
  877. <li>Problem Antrieb, rechts</li>
  878. <li>Problem Antrieb, links</li>
  879. <li>Schneidsystem blockiert</li>
  880. <li>Fehlerhafte Verbindung</li>
  881. <li>Standardeinstellungen</li>
  882. <li>Elektronisches Problem</li>
  883. <li>Problem Ladesystem</li>
  884. <li>Kippsensorproblem</li>
  885. <li>Rechter Radmotor &uuml;berlastet</li>
  886. <li>Linker Radmotor &uuml;berlastet</li>
  887. <li>Ladestrom zu hoch</li>
  888. <li>Vor&uuml;bergehendes Problem</li>
  889. <li>SK 1 nicht gefunden</li>
  890. <li>SK 2 nicht gefunden</li>
  891. <li>SK 3 nicht gefunden</li>
  892. <li>Problem die Ladestation zu finden</li>
  893. <li>Kalibration des Suchkabels beendet</li>
  894. <li>Kalibration des Suchkabels fehlgeschlagen</li>
  895. <li>Kurzzeitiges Batterieproblem</li>
  896. <li>Batterieproblem</li>
  897. <li>Alarm! M&auml;her ausgeschalten</li>
  898. <li>Alarm! M&auml;her gestoppt</li>
  899. <li>Alarm! M&auml;her angehoben</li>
  900. <li>Alarm! M&auml;her gekippt</li>
  901. <li>Verbindung geändert</li>
  902. <li>Verbindung nicht ge&auml;ndert</li>
  903. <li>COM board nicht verf&uuml;gbar</li>
  904. <li>Rutscht</li>
  905. </ul>
  906. </li>
  907. <li>mower-manual_operation - Manueller Betrieb (0/1) oder mit neuerer Firmware (false/true)</li>
  908. <li>mower-override_end_time - Zeitpunkt wann der manuelle Betrieb beendet ist</li>
  909. <li>mower-source_for_next_start - Grund f&uuml;r den n&auml;chsten Start
  910. <ul>
  911. <li>Kein Grund</li>
  912. <li>M&auml;her wurde geladen</li>
  913. <li>SensorControl erreicht</li>
  914. <li>Wochentimer erreicht</li>
  915. <li>Stoppuhr Timer</li>
  916. <li>Undefiniert</li>
  917. </ul>
  918. </li>
  919. <li>mower-status - M&auml;her Status (siehe state)</li>
  920. <li>mower-timestamp_next_start - Zeitpunkt des n&auml;chsten geplanten Starts</li>
  921. <li>radio-connection_status - Status der Funkverbindung</li>
  922. <li>radio-quality - Indikator f&uuml;r die Funkverbindung in Prozent</li>
  923. <li>radio-state - radio state (schlecht/schwach/gut/Undefiniert)</li>
  924. <li>state - Staus des M&auml;hers
  925. <ul>
  926. <li>Pausiert</li>
  927. <li>M&auml;hen</li>
  928. <li>Suche Ladestation</li>
  929. <li>L&auml;dt</li>
  930. <li>M&auml;hen</li>
  931. <li>Wird aktualisiert ...</li>
  932. <li>Wird eingeschaltet ...</li>
  933. <li>Geparkt nach Zeitplan</li>
  934. <li>Geparkt</li>
  935. <li>Der M&auml;her ist ausgeschaltet</li>
  936. <li>Deaktiviert. Abdeckung ist offen oder PIN-Code erforderlich</li>
  937. <li>Unbekannter Status</li>
  938. <li>Fehler</li>
  939. <li>Neustart ...</li>
  940. <li>Deaktiviert. Manueller Start erforderlich</li>
  941. <li>Manuelles M&auml;hen</li>
  942. <li>Geparkt durch SensorControl</li>
  943. <li>Abgeschlossen</li>
  944. </ul>
  945. </li>
  946. </ul>
  947. <br><br>
  948. <a name="GardenaSmartDeviceattributes"></a>
  949. <b>Attribute</b>
  950. <ul>
  951. <li>readingValueLanguage - &Auml;nderung der Sprache der Readings (de,en/wenn nichts gesetzt ist, dann Englisch es sei denn deutsch ist als globale Sprache gesetzt) </li>
  952. <li>model - </li>
  953. </ul>
  954. <a name="GardenaSmartDeviceset"></a>
  955. <b>set</b>
  956. <ul>
  957. <li>parkUntilFurtherNotice - Parken des M&auml;hers unter Umgehung des Zeitplans</li>
  958. <li>parkUntilNextTimer - Parken bis zum n&auml;chsten Zeitplan</li>
  959. <li>startOverrideTimer - Manuelles m&auml;hen (in Minuten, 60 = 1h, 1440 = 24h, 4320 = 72h)</li>
  960. <li>startResumeSchedule - Weiterf&uuml;hrung des Zeitplans</li>
  961. <li>startpoint enable|disable 1|2|3 - Aktiviert oder deaktiviert einen vordefinierten Startbereich</li>
  962. <ul>
  963. <li>set NAME startpoint enable 1</li>
  964. <li>set NAME startpoint disable 3 enable 1</li>
  965. </ul>
  966. </ul>
  967. </ul>
  968. =end html_DE
  969. =cut