98_exportdevice.pm 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. # $Id: 98_exportdevice.pm 12047 2016-08-22 08:06:24Z loredo $
  2. package main;
  3. use strict;
  4. use warnings;
  5. no if $] >= 5.017011, warnings => 'experimental';
  6. sub CommandExportdevice($$);
  7. ########################################
  8. sub exportdevice_Initialize($$) {
  9. my %hash = (
  10. Fn => "CommandExportdevice",
  11. Hlp => "[devspec] [quote] [dependent]",
  12. );
  13. $cmds{exportdevice} = \%hash;
  14. }
  15. ########################################
  16. sub CommandExportdevice($$) {
  17. my ( $cl, $param ) = @_;
  18. my @a = split( "[ \t][ \t]*", $param );
  19. my $quote = 0;
  20. my $dependent = 0;
  21. my $str = "";
  22. return "Usage: exportdevice [devspec] [quote] [dependent]"
  23. if ( $a[0] eq "?" );
  24. $dependent = 1
  25. if ( $a[0] eq "dependent"
  26. || $a[1] eq "dependent"
  27. || $a[1] eq "dependent" );
  28. $quote = 1
  29. if ( $a[0] eq "quote" || $a[1] eq "quote" || $a[2] eq "quote" );
  30. $a[0] = ".*"
  31. if ( int(@a) < 1
  32. || $a[0] eq "quote"
  33. || $a[0] eq "dependent" );
  34. my $mname = "";
  35. my @objects;
  36. foreach my $d ( devspec2array( $a[0], $cl ) ) {
  37. next if ( !$defs{$d} || $d ~~ @objects );
  38. push( @objects, $d );
  39. # w/ module header
  40. if ( $mname ne $defs{$d}{TYPE} ) {
  41. $mname = $defs{$d}{TYPE};
  42. $str .= CommandExportdeviceGetBlock( $d, $quote, 1 );
  43. }
  44. # w/o module header
  45. else {
  46. $str .= CommandExportdeviceGetBlock( $d, $quote );
  47. }
  48. if ($dependent) {
  49. # dependent objects
  50. my $dc = 0;
  51. foreach my $do ( CommandExportdeviceGetDependentObjects($d) ) {
  52. next if ( !$do || $do eq $d || $do ~~ @objects );
  53. push( @objects, $do );
  54. $dc++;
  55. $str .= "#+++ Dependent objects"
  56. if $dc == 1;
  57. # w/ module header
  58. if ( $mname ne $defs{$do}{TYPE} ) {
  59. $mname = $defs{$do}{TYPE};
  60. my $s = CommandExportdeviceGetBlock( $do, $quote, 1 );
  61. $s =~ s/\n/\n /g;
  62. $str .= $s;
  63. }
  64. # w/o module header
  65. else {
  66. my $s = CommandExportdeviceGetBlock( $do, $quote );
  67. $s =~ s/\n/\n /g;
  68. $str .= $s;
  69. }
  70. }
  71. }
  72. }
  73. my $return;
  74. $return = "#\n# Flat Export created by "
  75. if ( !$quote );
  76. $return = "#\n# Quoted Export created by "
  77. if ($quote);
  78. return
  79. $return
  80. . AttrVal( "global", "version", "fhem.pl:?/?" )
  81. . "\n# at "
  82. . TimeNow() . "\n#"
  83. . $str . "\n\n"
  84. if ( $str ne "" );
  85. return "No device found: $a[0]";
  86. }
  87. sub CommandExportdeviceGetBlock($$;$) {
  88. my ( $d, $quote, $h ) = @_;
  89. my $str = "";
  90. return if ( !$defs{$d} );
  91. # module header (only once)
  92. if ($h) {
  93. my $ver = fhem( "version " . $defs{$d}{TYPE}, 1 );
  94. $ver =~ s/\n+/\n# /g;
  95. $ver =~ s/^/# /g;
  96. $str .= "\n\n### TYPE: $defs{$d}{TYPE}\n$ver\n\n";
  97. }
  98. # device definition
  99. if ( $d ne "global" ) {
  100. my $def = $defs{$d}{DEF};
  101. if ( defined($def) ) {
  102. if ($quote) {
  103. $def =~ s/;/;;/g;
  104. $def =~ s/\n/\\\n/g;
  105. }
  106. $str .= "define $d $defs{$d}{TYPE} $def\n";
  107. }
  108. else {
  109. $str .= "define $d $defs{$d}{TYPE}\n";
  110. }
  111. }
  112. # device attributes
  113. foreach my $a (
  114. sort {
  115. return -1
  116. if ( $a eq "userattr" ); # userattr must be first
  117. return 1 if ( $b eq "userattr" );
  118. return $a cmp $b;
  119. } keys %{ $attr{$d} }
  120. )
  121. {
  122. next
  123. if ( $d eq "global"
  124. && ( $a eq "configfile" || $a eq "version" ) );
  125. my $val = $attr{$d}{$a};
  126. if ($quote) {
  127. $val =~ s/;/;;/g;
  128. $val =~ s/\n/\\\n/g;
  129. }
  130. $str .= "attr $d $a $val\n";
  131. }
  132. $str .= "\n";
  133. return $str;
  134. }
  135. sub CommandExportdeviceGetDependentObjects($) {
  136. my ($d) = @_;
  137. my @dob;
  138. foreach my $dn ( sort keys %defs ) {
  139. next if ( !$dn || $dn eq $d );
  140. my $dh = $defs{$dn};
  141. if ( ( $dh->{DEF} && $dh->{DEF} =~ m/\b$d\b/ )
  142. || ( $defs{$d}{DEF} && $defs{$d}{DEF} =~ m/\b$dn\b/ ) )
  143. {
  144. push( @dob, $dn );
  145. }
  146. }
  147. return @dob;
  148. }
  149. 1;
  150. =pod
  151. =item command
  152. =item summary exports definition and attributes of devices
  153. =item summary_DE exportiert die Definition und die Attribute von Ger&auml;ten
  154. =begin html
  155. <a name="exportdevice"></a>
  156. <h3>exportdevice</h3>
  157. <ul>
  158. <code>exportdevice [devspec] [quote] [dependent]</code>
  159. <br><br>
  160. Output a complete device and attribute definition of FHEM devices. This is
  161. one of the few commands which return a string in a normal case.<br>
  162. See the <a href="#devspec">Device specification</a> section for details on
  163. &lt;devspec&gt;.
  164. <br><br>
  165. The output can be used for reimport using FHEMWEB or telnet command line.<br>
  166. The optional paramter "quote" may be added to receive fhem.cfg compatible output.
  167. <br><br>
  168. Example:
  169. <pre><code> fhem> exportdevice Office
  170. #
  171. # Export created by fhem.pl:12022/2016-08-21
  172. # on 2016-08-22 01:02:59
  173. #
  174. ### TYPE: FS20
  175. # File Rev Last Change
  176. # 10_FS20.pm 11984 2016-08-19 12:47:50Z rudolfkoenig
  177. define Office FS20 1234 12
  178. attr Office userattr Light Light_map structexclude
  179. attr Office IODev CUL_0
  180. attr Office Light AllLights
  181. attr Office group Single Lights
  182. attr Office icon light_office
  183. attr Office model fs20st
  184. attr Office room Light
  185. </code></pre>
  186. </ul>
  187. =end html
  188. =begin html_DE
  189. <a name="exportdevice"></a>
  190. <h3>exportdevice</h3>
  191. <ul>
  192. <code>exportdevice [devspec] [quote] [dependent]</code>
  193. <br><br>
  194. Gibt die komplette Definition und Attribute eines FHEM Ger&auml;tes aus. Dies
  195. ist eines der wenigen Befehle, die im Normalfall eine Zeichenkette ausgeben.<br>
  196. Siehe den Abschnitt &uuml;ber <a href="#devspec">Ger&auml;te-Spezifikation</a>
  197. f&uuml;r Details der &lt;devspec&gt;.
  198. <br><br>
  199. Die Ausgabe kann f&uuml;r einen Reimport mittels FHEMWEB oder Telnet
  200. Kommandozeile verwendet werden.<br>
  201. Der optionale Parameter "quote" kann genutzt werden, um eine fhem.cfg
  202. kompatible Ausgabe zu erhalten.
  203. <br><br>
  204. Beispiel:
  205. <pre><code> fhem> exportdevice Office
  206. #
  207. # Export created by fhem.pl:12022/2016-08-21
  208. # on 2016-08-22 01:02:59
  209. #
  210. ### TYPE: FS20
  211. # File Rev Last Change
  212. # 10_FS20.pm 11984 2016-08-19 12:47:50Z rudolfkoenig
  213. define Office FS20 1234 12
  214. attr Office userattr Light Light_map structexclude
  215. attr Office IODev CUL_0
  216. attr Office Light AllLights
  217. attr Office group Single Lights
  218. attr Office icon light_office
  219. attr Office model fs20st
  220. attr Office room Light
  221. </code></pre>
  222. </ul>
  223. =end html_DE
  224. =cut