Datenauswertung mit dem SPN 1000

Der SPN1000 erlaubt es, Daten über die serielle Schnittstelle auszulesen. Hier ein Weg, das mit frei verfügbarer kostenloser Software auch auf aktuellen PCs (oder Mac, WRT54G, dbox2,...) zu bewerkstelligen.

Der Wechselrichter erwartet eine Anfrage und wirft dann die dazugehörigen Daten aus. Hier wird nur die aktuelle Leistung am Netz ausgewertet, andere Daten gibts aber analog dazu (siehe Liste)
Verwendet werden zur Abfrage Perl (mit Device::SerialPort) und rrdtool als Datenbank und für die grafische Aufbereitung.
Beispielgrafik: Leistung am Netz


Da der Wechselrichter nur per Rx,Tx (gekreuzt) und GND kommuniziert, muß einerseits der Hardware-Handshake mittels stty deaktiviert werden - oder am Kabel die Pins 4 und 7 (RTS, CTS) brücken. Zusätzlich besteht das Problem, daß ein ausgeschalteter Wechselrichter nicht erkannt werden kann, daher der Umweg über den Alarm.
Weil hier jedoch 2 Wechselrichter im Winsatz sind kommt noch ein wenig Bastelei hinzu, um mit einer kleinen Schaltung zwischen den beiden Geräten auszuwälen (d.h. nur 1 serielles Kabel vom PC zu den Wechselrichtern).
Genutzt wird die DTR-Leitung, um einen analogen Schalter zu steuern, der zwischen den beiden Rx-Leitungen umschaltet. Leider ist dies mit sysopen und stty nicht machbar, darum wird jetzt Device::SerialPort genutzt.




1	#!/usr/bin/perl

2	# Thomas Hog, 2007-04-22; 2008-01-20

3	# ToDo:   *Request onthefly generieren (inkl Checksumme)

4	#    *BCC der Antwort verifizieren

5	#    *Abfragen in ein Array packen?

6	#--------------------------------------------------------

7	use Device::SerialPort;

8	$lockfile = "/tmp/spn-statistik.pl.lock";

9	exit if (-e $lockfile);

10	open(OUT,">$lockfile") or die "Cannot lock: $!";close(OUT);

11

12	$wert =""; # seriell eingelesener Wert

13	$check_input = "1"; # Eingelesene Daten auf Uebertragungsfehler pruefen

14	$SPNPORT = "/dev/ttyS1";

15	my @Daten = ("","");

16	$SPNNUMMER="";

17	$CTIME = localtime(time);

18	#$UNIXTIME = time();

19	my ($Sekunden, $Minuten, $Stunden, $Monatstag, $Monat, $Jahr, $Wochentag, $Jahrestag, $Sommerzeit) = localtime((time)-86400);

20	$Monat+=1;

21	$Jahrestag+=1;

22	$Monat = $Monat < 10 ? $Monat = "0".$Monat : $Monat;

23	$Monatstag = $Monatstag < 10 ? $Monatstag = "0".$Monatstag : $Monatstag;

24	$Jahr+=1900;

25	$ISODATUMVORTAG = "$Jahr-$Monat-$Monatstag";

26	$Monat-=1;

27	if ($Monat eq "0") {$Monat=12; $Jahr-=1;}

28	$Monat = $Monat < 10 ? $Monat = "0".$Monat : $Monat;

29	$ISODATUMVORMONAT = "$Jahr-$Monat";

30

31	# Was tun?

32	if    ($ARGV[0] eq "leistung")   {doleistung();}

33	elsif ($ARGV[0] eq "kwh-vortag") {dokwhvortag();}

34	elsif ($ARGV[0] eq "kwh-vormonat") {dokwhvormonat();}

35	elsif ($ARGV[0] eq "kwh-vorjahr") {dokwhvorjahr();}

36	elsif ($ARGV[0] eq "uac")        {douac();}

37	elsif ($ARGV[0] eq "stat-monat") {dostatmonat();}

38	elsif ($ARGV[0] eq "stat-tag")   {dostattag();}

39	elsif ($ARGV[0] eq "checksum")   {checksum();}

40	elsif ($ARGV[0] eq "fehlerpuffer") {dofehlerpuffer();}

41	else {

42	printf("Fehler: Unbekannter Aufruf!\n");

43	printf("Gültige Optionen: leistung | kwh-vor{tag|monat|jahr} | uac | stat-{monat|tag} | fehlerpuffer | checksum 1 2 3 4\n");

44	printf("Bei zusätzlicher Angabe \"rrdtool\" wird bei leistung nicht auf STDOUT sondern die Datenbank ausgegeben.\n");

45	ausgang();

46	}

47

48	my @Fehlerpufferdaten=("Tag","Monat","Jahr","Stunde","Minute","Sekunde","Status");

49	# beim Beenden Lockfile wieder entfernen

50	sub ausgang {

51	unlink($lockfile);

52	#                  Lockfile aufräumen. Hoffentlich ist jeder Fall 

53	#                  abgedeckt, sonst gibts bis zum 

54	#                  manuellen Löschen der Datei nix neues :(

55	}

56

57	#------------------------------------------------------------------------------

58	# Funktionen... 

59	# 0 == Wechselrichter 1 (DTR aus) || 1 == WR 2 (DTR ein)

60

61	sub dostatmonat {

62	initialisierung (0);

63	monate ();

64	undef $ob;

65	initialisierung (1);

66	monate();

67	undef $ob;

68	ausgang();

69	}

70

71	sub dostattag {

72	initialisierung (0);

73	tage();

74	undef $ob;

75	initialisierung (1);

76	tage();

77	undef $ob;

78	ausgang();

79	}

80

81	sub doleistung {

82	initialisierung (0);

83	leistung ();

84	undef $ob;

85	initialisierung (1);

86	leistung ();

87	undef $ob;

88

89	# Weiterverarbeitung via RRDTool

90	if ($ARGV[1] eq "rrdtool") {

91	system("/usr/bin/rrdtool","update","/usr/local/bin/solar-rrd/solar.rrd","N:$Daten[0]:$Daten[1]"); }

92	else

93	{printf("Leistung am Netz: SPN1: %.1f W | SPN2: %.1f W\n", $Daten[0]/100, $Daten[1]/100);}

94	#printf("/usr/bin/rrdtool update /usr/local/bin/solar-rrd/solar.rrd N:%.0f:%.0f\n",$Daten[0],$Daten[1]);

95	#system("/bin/echo $UNIXTIME $rrdwert - $CTIME - Hi: $hwert2 - Lo: $hwert >> /var/log/solar.log");

96	ausgang();

97	}

98

99	sub dokwhvortag {

100	initialisierung (0);

101	kwhvortag ();

102	undef $ob;

103	initialisierung (1);

104	kwhvortag ();

105	undef $ob;

106	printf ("$ISODATUMVORTAG  %5.1f %5.1f  %5.1f\n",$Daten[0],$Daten[1],$Daten[0]+$Daten[1]);

107	ausgang();

108	}

109

110	sub dokwhvormonat {

111	initialisierung (0);

112	kwhvormonat();

113	undef $ob;

114	initialisierung (1);

115	kwhvormonat();

116	undef $ob;

117	printf ("S:$ISODATUMVORMONAT     %5.1f %5.1f  %5.1f\n==============================\n",$Daten[0],$Daten[1],$Daten[0]+$Daten[1]);

118	ausgang();

119	}

120

121	sub sokwhvorjahr {

122	initialisierung (0);

123	kwhvorjahr();

124	undef $ob;

125	initialisierung (1);

126	kwhvorjahr();

127	undef $ob;

128	printf ("------------------------------\nS:$ISODATUMVORMONAT     %5.1f %5.1f  %5.1f\n==============================\n",$Daten[0],$Daten[1],$Daten[0]+$Daten[1]);

129	ausgang();

130	}

131

132	sub douac {

133	initialisierung (0);

134	uac();

135	undef $ob;

136	initialisierung (1);

137	uac();

138	undef $ob;

139	printf ("Uac(1): $Daten[0] | Uac(2): $Daten[1]\n");

140	ausgang();

141	}

142

143

144	#------------------------------------------------------------------------------

145	###############

146	# SubFunktionen

147	###############

148	sub initialisierung {

149	### Serielle Schnittstelle definieren

150	$SPNNUMMER = shift;

151	$ob = Device::SerialPort->new ($SPNPORT) || {ausgang() && die "Can't open $SPNPORT:$!"};

152	$ob->baudrate (1200) || {ausgang() && die "fail setting baudrate"};

153	$ob->parity ("even") || {ausgang() && die "fail setting parity"};

154	$ob->databits (8) || {ausgang() && die "fail setting databits"};

155	$ob->stopbits (1) || {ausgang() && die "fail setting stopbits"};

156	$ob->handshake ("none") || {ausgang() && die "fail setting handshake"};

157	$ob->dtr_active ($SPNNUMMER) || {ausgang() && die "fail setting dtr_active"};

158	$ob->write_settings || {ausgang() && die "no settings"};

159	local $SIG{ALRM} = sub {ausgang() && die "Alarm"};

160	sleep 1;

161	alarm(8); # ~5 mal nix (brauchbares) lesen reicht aus

162	} #initialisierung

163

164	sub Einlesen {

165	my $Request = shift;

166	my $input;

167	eval {

168	   local $SIG{ALRM} = sub { ausgang() && die };

169	   #sleep(1); # sicherstellen, daß die Leitung frei/leer ist...

170	   $ob->write("$Request") or die ("Could not write!");

171	   sleep 1;

172	   $input = $ob->input;

173	   };

174	if ($@ and $@ !~ /Alarm/) {

175	   undef $ob;

176	   die "Timeout! - $CTIME\n";

177	   }

178

179	if (length($input) ne "13") {Einlesen($Request);} #Kann zwar nicht sein, passiert aber ;(

180	alarm(0);

181	$wert=$input;

182	if ($check_input){

183	      if (Check($wert) ne "1") {

184	      #   sleep(1);

185	         Einlesen($Request);#  Uebertragungsfehler - nochmal!

186	         }

187	      }

188	}#einlesen

189

190	sub Check {

191	my $String = shift;

192	# Aufbau der Antwort: (STX) 005300 [DATA] (ETX) (BCC)

193	my $antwort = substr($String,1,6);

194	if ($antwort ne "005300"){

195	        if ($BCC_CHECK_DEBUG){

196	   printf(STDERR "Fehlerhafte Antwort: $antwort\n")};

197	           return(0);

198	              };

199	my $byte1 = ord(substr($String,7,1));  #1. Byte der Antwort

200	my $byte2 = ord(substr($String,8,1));  #2. Byte der Antwort

201	my $byte3 = ord(substr($String,9,1));  #3. Byte der Antwort

202	my $byte4 = ord(substr($String,10,1)); #4. Byte der Antwort

203	my $byte8 = ord(substr($String,12,1)); #BCC-Hash der Antwort

204

205	# Xor-Wert fuer 'STX 005300 ETX' ist x07

206	if ((0x07^$byte1^$byte2^$byte3^$byte4) ne $byte8)

207	   {

208	   if ($BCC_CHECK_DEBUG){

209	      printf(STDERR "BCC-Fehler! ");

210	      printf(STDERR "Soll: %02x \<-\> Ist: %02x \(%02x, %02x, %02x, %02x\)\n",\

211	      0x02^0x30^0x30^0x35^0x33^0x30^0x30^0x03^$byte1^$byte2^$byte3^$byte4,$byte8,\

212	      $byte1,$byte2,$byte3,$byte4);

213	      }

214	   return(0);

215	   }

216	if ($BCC_CHECK_DEBUG){ printf (STDERR "BCC okay!\n"); }

217	return(1);

218	}#check

219

220

221	sub BCC {

222	my $Hash = shift;

223	$Hash =~/(.)(.)(.)(.)$/;

224	my $byte1 = ord($1);

225	my $byte2 = ord($2);

226	my $byte3 = ord($3);

227	my $byte4 = ord($4);

228	#printf (STDERR "%02x\n",0x02^0x30^0x30^0x35^0x33^0x3F^0x3F^$byte1^$byte2^$byte3^$byte4^0x03);

229	return(7^$byte1^$byte2^$byte3^$byte4);

230	}#bcc

231

232	# Checksummen berechnen

233	sub checksum {

234

235	if ($ARGV[1] eq "" || $ARGV[2] eq "" || $ARGV[3] eq "" || $ARGV[4] eq "")

236	{printf("Fehlerhafte Daten. Aufruf zB: $0 checksum C F F 6\n");}

237	else {printf("%02X\n", 7^ ord($ARGV[1])^ ord($ARGV[2]) ^ ord($ARGV[3]) ^ ord($ARGV[4])); }

238	ausgang();

239	}#checksum

240

241	sub uac {

242	Einlesen("\0020053??03E6\003\x77");

243	$Daten[$SPNNUMMER]= sprintf("%.1f", hex(substr($wert,7,4))/10);

244	}

245

246	sub kwhvortag {

247	Einlesen("\0020053??CFF6\003\x72"); # Low-Bytes

248	$hwert = substr($wert,7,4);

249	Einlesen("\0020053??CFF8\003\x7C"); # High-Bytes

250	$hwert2 = substr($wert,7,4);

251	$Daten[$SPNNUMMER] = sprintf("%5.1f",hex($hwert2.$hwert)/10);

252	}

253

254	sub kwhvormonat {

255	Einlesen("\0020053??CFEE\003\x02"); # Low-Bytes

256	$hwert = substr($wert,7,4);

257	Einlesen("\0020053??CFF0\003\x74"); # High-Bytes

258	$hwert2 = substr($wert,7,4);

259	$Daten[$SPNNUMMER] = sprintf("%5.1f",hex($hwert2.$hwert)/10);

260	}

261

262	sub kwhvorjahr {

263	Einlesen("\0020053??CFE6\003\x71"); # Low-Bytes

264	$hwert = substr($wert,7,4);

265	Einlesen("\0020053??CFE8\003\x7f"); # High-Bytes

266	$hwert2 = substr($wert,7,4);

267	$Daten[$SPNNUMMER] = sprintf("%5.1f",hex($hwert2.$hwert)/10);

268	}

269

270	sub leistung {

271	# Leistung (Lo & Hi, da mehr als FFFF moeglich.

272	Einlesen("\0020053??03EA\003\x00"); # low-Bytes

273	$hwert = substr($wert,7,4);

274	$wert="";

275	Einlesen("\0020053??03EC\003\x02"); # High-Bytes

276	$hwert2 = substr($wert,7,4);

277	$rrdwert=sprintf("%.0f",hex($hwert2.$hwert));

278	if ($rrdwert >= 60 && $rrdwert <= 110000){

279	$Daten[$SPNNUMMER] = hex($hwert2.$hwert);}

280	}

281

282	##

283	# Vorsicht, ab hier wirds ekelhaft. 

284	# Sollte auch hübscher gehen, aber es funktioniert ;-)

285	##

286

287	sub monate{

288	printf("Wechselrichter %1i:\n.................\n",$SPNNUMMER+1);

289	Einlesen("\0020053??CFE6\003\x71"); # Low-Bytes

290	$hwert = substr($wert,7,4);

291	Einlesen("\0020053??CFE8\003\x7f"); # High-Bytes

292	$hwert2 = substr($wert,7,4);

293	printf ("Vorjahr: %5.1f\n",hex($hwert2.$hwert)/10);

294

295	Einlesen("\0020053??CF26\003\x06"); # Low-Bytes

296	$hwert = substr($wert,7,4);

297	Einlesen("\0020053??CF28\003\x08"); # High-Bytes

298	$hwert2 = substr($wert,7,4);

299	printf ("Januar: %5.1f\n",hex($hwert2.$hwert)/10);

300

301	Einlesen("\0020053??CF2A\003\x71"); # Low-Bytes

302	$hwert = substr($wert,7,4);

303	Einlesen("\0020053??CF2C\003\x73"); # High-Bytes

304	$hwert2 = substr($wert,7,4);

305	printf ("Februar: %5.1f\n",hex($hwert2.$hwert)/10);

306

307	Einlesen("\0020053??CF2E\003\x75"); # Low-Bytes

308	$hwert = substr($wert,7,4);

309	Einlesen("\0020053??CF30\003\x01"); # High-Bytes

310	$hwert2 = substr($wert,7,4);

311	printf ("Maerz: %5.1f\n",hex($hwert2.$hwert)/10);

312

313	Einlesen("\0020053??CF32\003\x03"); # Low-Bytes

314	$hwert = substr($wert,7,4);

315	Einlesen("\0020053??CF34\003\x05"); # High-Bytes

316	$hwert2 = substr($wert,7,4);

317	printf ("April: %5.1f\n",hex($hwert2.$hwert)/10);

318

319	Einlesen("\0020053??CF36\003\x07"); # Low-Bytes

320	$hwert = substr($wert,7,4);

321	Einlesen("\0020053??CF38\003\x09"); # High-Bytes

322	$hwert2 = substr($wert,7,4);

323	printf ("Mai: %5.1f\n",hex($hwert2.$hwert)/10);

324

325	Einlesen("\0020053??CF3A\003\x70"); # Low-Bytes

326	$hwert = substr($wert,7,4);

327	Einlesen("\0020053??CF3C\003\x72"); # High-Bytes

328	$hwert2 = substr($wert,7,4);

329	printf ("Juni: %5.1f\n",hex($hwert2.$hwert)/10);

330

331	Einlesen("\0020053??CF3E\003\x74"); # Low-Bytes

332	$hwert = substr($wert,7,4);

333	Einlesen("\0020053??CF40\003\x06"); # High-Bytes

334	$hwert2 = substr($wert,7,4);

335	printf ("Juli: %5.1f\n",hex($hwert2.$hwert)/10);

336

337	Einlesen("\0020053??CF42\003\x04"); # Low-Bytes

338	$hwert = substr($wert,7,4);

339	Einlesen("\0020053??CF44\003\x02"); # High-Bytes

340	$hwert2 = substr($wert,7,4);

341	printf ("August: %5.1f\n",hex($hwert2.$hwert)/10);

342

343	Einlesen("\0020053??CF46\003\x00"); # Low-Bytes

344	$hwert = substr($wert,7,4);

345	Einlesen("\0020053??CF48\003\x0E"); # High-Bytes

346	$hwert2 = substr($wert,7,4);

347	printf ("September: %5.1f\n",hex($hwert2.$hwert)/10);

348

349	Einlesen("\0020053??CF4A\003\x77"); # Low-Bytes

350	$hwert = substr($wert,7,4);

351	Einlesen("\0020053??CF4C\003\x75"); # High-Bytes

352	$hwert2 = substr($wert,7,4);

353	printf ("Oktober: %5.1f\n",hex($hwert2.$hwert)/10);

354

355	Einlesen("\0020053??CF4E\003\x73"); # Low-Bytes

356	$hwert = substr($wert,7,4);

357	Einlesen("\0020053??CF50\003\x07"); # High-Bytes

358	$hwert2 = substr($wert,7,4);

359	printf ("November: %5.1f\n",hex($hwert2.$hwert)/10);

360

361	Einlesen("\0020053??CF52\003\x05"); # Low-Bytes

362	$hwert = substr($wert,7,4);

363	Einlesen("\0020053??CF54\003\x03"); # High-Bytes

364	$hwert2 = substr($wert,7,4);

365	printf ("Dezember: %5.1f\n",hex($hwert2.$hwert)/10);

366	}#monate

367

368	sub tage{

369	printf("Wechselrichter %1i:\n.................\n",$SPNNUMMER+1);

370	Einlesen("\0020053??CF56\003\x01"); # Low-Bytes

371	$hwert = substr($wert,7,4);

372	Einlesen("\0020053??CF58\003\x0F"); # High-Bytes

373	$hwert2 = substr($wert,7,4);

374	printf ("Tag 01: %5.1f\n",hex($hwert2.$hwert)/10);

375	Einlesen("\0020053??CF5A\003\x76"); # Low-Bytes

376	$hwert = substr($wert,7,4);

377	Einlesen("\0020053??CF5C\003\x74"); # High-Bytes

378	$hwert2 = substr($wert,7,4);

379	printf ("Tag 02: %5.1f\n",hex($hwert2.$hwert)/10);

380	Einlesen("\0020053??CF5E\003\x72"); # Low-Bytes

381	$hwert = substr($wert,7,4);

382	Einlesen("\0020053??CF60\003\x04"); # High-Bytes

383	$hwert2 = substr($wert,7,4);

384	printf ("Tag 03: %5.1f\n",hex($hwert2.$hwert)/10);

385	Einlesen("\0020053??CF62\003\x06"); # Low-Bytes

386	$hwert = substr($wert,7,4);

387	Einlesen("\0020053??CF64\003\x00"); # High-Bytes

388	$hwert2 = substr($wert,7,4);

389	printf ("Tag 04: %5.1f\n",hex($hwert2.$hwert)/10);

390	Einlesen("\0020053??CF66\003\x02"); # Low-Bytes

391	$hwert = substr($wert,7,4);

392	Einlesen("\0020053??CF68\003\x0C"); # High-Bytes

393	$hwert2 = substr($wert,7,4);

394	printf ("Tag 05: %5.1f\n",hex($hwert2.$hwert)/10);

395	Einlesen("\0020053??CF6A\003\x75"); # Low-Bytes

396	$hwert = substr($wert,7,4);

397	Einlesen("\0020053??CF6C\003\x77"); # High-Bytes

398	$hwert2 = substr($wert,7,4);

399	printf ("Tag 06: %5.1f\n",hex($hwert2.$hwert)/10);

400	Einlesen("\0020053??CF6E\003\x71"); # Low-Bytes

401	$hwert = substr($wert,7,4);

402	Einlesen("\0020053??CF70\003\x05"); # High-Bytes

403	$hwert2 = substr($wert,7,4);

404	printf ("Tag 07: %5.1f\n",hex($hwert2.$hwert)/10);

405	Einlesen("\0020053??CF72\003\x07"); # Low-Bytes

406	$hwert = substr($wert,7,4);

407	Einlesen("\0020053??CF74\003\x01"); # High-Bytes

408	$hwert2 = substr($wert,7,4);

409	printf ("Tag 08: %5.1f\n",hex($hwert2.$hwert)/10);

410	Einlesen("\0020053??CF76\003\x03"); # Low-Bytes

411	$hwert = substr($wert,7,4);

412	Einlesen("\0020053??CF78\003\x0D"); # High-Bytes

413	$hwert2 = substr($wert,7,4);

414	printf ("Tag 09: %5.1f\n",hex($hwert2.$hwert)/10);

415	Einlesen("\0020053??CF7A\003\x74"); # Low-Bytes

416	$hwert = substr($wert,7,4);

417	Einlesen("\0020053??CF7C\003\x76"); # High-Bytes

418	$hwert2 = substr($wert,7,4);

419	printf ("Tag 10: %5.1f\n",hex($hwert2.$hwert)/10);

420	Einlesen("\0020053??CF7E\003\x70"); # Low-Bytes

421	$hwert = substr($wert,7,4);

422	Einlesen("\0020053??CF80\003\x0A"); # High-Bytes

423	$hwert2 = substr($wert,7,4);

424	printf ("Tag 11: %5.1f\n",hex($hwert2.$hwert)/10);

425	Einlesen("\0020053??CF82\003\x08"); # Low-Bytes

426	$hwert = substr($wert,7,4);

427	Einlesen("\0020053??CF84\003\x0E"); # High-Bytes

428	$hwert2 = substr($wert,7,4);

429	printf ("Tag 12: %5.1f\n",hex($hwert2.$hwert)/10);

430	Einlesen("\0020053??CF86\003\x0C"); # Low-Bytes

431	$hwert = substr($wert,7,4);

432	Einlesen("\0020053??CF88\003\x02"); # High-Bytes

433	$hwert2 = substr($wert,7,4);

434	printf ("Tag 13: %5.1f\n",hex($hwert2.$hwert)/10);

435	Einlesen("\0020053??CF8A\003\x7B"); # Low-Bytes

436	$hwert = substr($wert,7,4);

437	Einlesen("\0020053??CF8C\003\x79"); # High-Bytes

438	$hwert2 = substr($wert,7,4);

439	printf ("Tag 14: %5.1f\n",hex($hwert2.$hwert)/10);

440	Einlesen("\0020053??CF8E\003\x7F"); # Low-Bytes

441	$hwert = substr($wert,7,4);

442	Einlesen("\0020053??CF90\003\x0B"); # High-Bytes

443	$hwert2 = substr($wert,7,4);

444	printf ("Tag 15: %5.1f\n",hex($hwert2.$hwert)/10);

445	Einlesen("\0020053??CF92\003\x09"); # Low-Bytes

446	$hwert = substr($wert,7,4);

447	Einlesen("\0020053??CF94\003\x0F"); # High-Bytes

448	$hwert2 = substr($wert,7,4);

449	printf ("Tag 16: %5.1f\n",hex($hwert2.$hwert)/10);

450	Einlesen("\0020053??CF96\003\x0D"); # Low-Bytes

451	$hwert = substr($wert,7,4);

452	Einlesen("\0020053??CF98\003\x03"); # High-Bytes

453	$hwert2 = substr($wert,7,4);

454	printf ("Tag 17: %5.1f\n",hex($hwert2.$hwert)/10);

455	Einlesen("\0020053??CF9A\003\x7A"); # Low-Bytes

456	$hwert = substr($wert,7,4);

457	Einlesen("\0020053??CF9C\003\x78"); # High-Bytes

458	$hwert2 = substr($wert,7,4);

459	printf ("Tag 18: %5.1f\n",hex($hwert2.$hwert)/10);

460	Einlesen("\0020053??CF9E\003\x7E"); # Low-Bytes

461	$hwert = substr($wert,7,4);

462	Einlesen("\0020053??CFA0\003\x73"); # High-Bytes

463	$hwert2 = substr($wert,7,4);

464	printf ("Tag 19: %5.1f\n",hex($hwert2.$hwert)/10);

465	Einlesen("\0020053??CFA2\003\x71"); # Low-Bytes

466	$hwert = substr($wert,7,4);

467	Einlesen("\0020053??CFA4\003\x77"); # High-Bytes

468	$hwert2 = substr($wert,7,4);

469	printf ("Tag 20: %5.1f\n",hex($hwert2.$hwert)/10);

470	Einlesen("\0020053??CFA6\003\x75"); # Low-Bytes

471	$hwert = substr($wert,7,4);

472	Einlesen("\0020053??CFA8\003\x7B"); # High-Bytes

473	$hwert2 = substr($wert,7,4);

474	printf ("Tag 21: %5.1f\n",hex($hwert2.$hwert)/10);

475	Einlesen("\0020053??CFAA\003\x02"); # Low-Bytes

476	$hwert = substr($wert,7,4);

477	Einlesen("\0020053??CFAC\003\x00"); # High-Bytes

478	$hwert2 = substr($wert,7,4);

479	printf ("Tag 22: %5.1f\n",hex($hwert2.$hwert)/10);

480	Einlesen("\0020053??CFAE\003\x06"); # Low-Bytes

481	$hwert = substr($wert,7,4);

482	Einlesen("\0020053??CFB0\003\x70"); # High-Bytes

483	$hwert2 = substr($wert,7,4);

484	printf ("Tag 23: %5.1f\n",hex($hwert2.$hwert)/10);

485	Einlesen("\0020053??CFB2\003\x72"); # Low-Bytes

486	$hwert = substr($wert,7,4);

487	Einlesen("\0020053??CFB4\003\x74"); # High-Bytes

488	$hwert2 = substr($wert,7,4);

489	printf ("Tag 24: %5.1f\n",hex($hwert2.$hwert)/10);

490	Einlesen("\0020053??CFB6\003\x76"); # Low-Bytes

491	$hwert = substr($wert,7,4);

492	Einlesen("\0020053??CFB8\003\x78"); # High-Bytes

493	$hwert2 = substr($wert,7,4);

494	printf ("Tag 25: %5.1f\n",hex($hwert2.$hwert)/10);

495	Einlesen("\0020053??CFBA\003\x01"); # Low-Bytes

496	$hwert = substr($wert,7,4);

497	Einlesen("\0020053??CFBC\003\x03"); # High-Bytes

498	$hwert2 = substr($wert,7,4);

499	printf ("Tag 26: %5.1f\n",hex($hwert2.$hwert)/10);

500	Einlesen("\0020053??CFBE\003\x05"); # Low-Bytes

501	$hwert = substr($wert,7,4);

502	Einlesen("\0020053??CFC0\003\x71"); # High-Bytes

503	$hwert2 = substr($wert,7,4);

504	printf ("Tag 27: %5.1f\n",hex($hwert2.$hwert)/10);

505	Einlesen("\0020053??CFC2\003\x73"); # Low-Bytes

506	$hwert = substr($wert,7,4);

507	Einlesen("\0020053??CFC4\003\x75"); # High-Bytes

508	$hwert2 = substr($wert,7,4);

509	printf ("Tag 28: %5.1f\n",hex($hwert2.$hwert)/10);

510	Einlesen("\0020053??CFC6\003\x77"); # Low-Bytes

511	$hwert = substr($wert,7,4);

512	Einlesen("\0020053??CFC8\003\x79"); # High-Bytes

513	$hwert2 = substr($wert,7,4);

514	printf ("Tag 29: %5.1f\n",hex($hwert2.$hwert)/10);

515	Einlesen("\0020053??CFCA\003\x00"); # Low-Bytes

516	$hwert = substr($wert,7,4);

517	Einlesen("\0020053??CFCC\003\x02"); # High-Bytes

518	$hwert2 = substr($wert,7,4);

519	printf ("Tag 30: %5.1f\n",hex($hwert2.$hwert)/10);

520	Einlesen("\0020053??CFCE\003\x04"); # Low-Bytes

521	$hwert = substr($wert,7,4);

522	Einlesen("\0020053??CFD0\003\x76"); # High-Bytes

523	$hwert2 = substr($wert,7,4);

524	printf ("Tag 31: %5.1f\n",hex($hwert2.$hwert)/10);

525	}#tage

526

527	sub dofehlerpuffer {

528	##

529	# tut noch nicht...

530	##

531	my $zaehler = 49152;

532	my $laufzahl = 1;

533	#while ($zaehler <= 49851) {

534	$hexzaehler= sprintf ("%4X",$zaehler);

535	printf ("Einlesen\(\"\\0020053??%04X\\003\\x%02X\"\)\n",$zaehler, 7^ ord(substr($hexzaehler,0,1)) ^ ord(substr($hexzaehler,1,1)) ^ ord(substr($hexzaehler,2,1)) ^ ord(substr($hexzaehler,3,1)));

536	#printf ("\$hwert = substr\(\$wert,7,4\);\n\n");

537	printf ("\$Fehlerpufferdaten[0] = substr\(\$wert,7,4\);\n\n");

538	$zaehler++;

539	$hexzaehler= sprintf ("%4X",$zaehler);

540	printf ("Einlesen\(\"\\0020053??%04X\\003\\x%02X\"\)\n",$zaehler, 7^ ord(substr($hexzaehler,0,1)) ^ ord(substr($hexzaehler,1,1)) ^ ord(substr($hexzaehler,2,1)) ^ ord(substr($hexzaehler,3,1)));

541	printf ("\$Fehlerpufferdaten[0] = substr\(\$wert,7,4\);\n\n");

542	$zaehler++;

543	$hexzaehler= sprintf ("%4X",$zaehler);

544	printf ("Einlesen\(\"\\0020053??%04X\\003\\x%02X\"\)\n",$zaehler, 7^ ord(substr($hexzaehler,0,1)) ^ ord(substr($hexzaehler,1,1)) ^ ord(substr($hexzaehler,2,1)) ^ ord(substr($hexzaehler,3,1)));

545	printf ("\$Fehlerpufferdaten[1] = substr\(\$wert,7,4\);\n\n");

546	$zaehler++;

547	$hexzaehler= sprintf ("%4X",$zaehler);

548	printf ("Einlesen\(\"\\0020053??%04X\\003\\x%02X\"\)\n",$zaehler, 7^ ord(substr($hexzaehler,0,1)) ^ ord(substr($hexzaehler,1,1)) ^ ord(substr($hexzaehler,2,1)) ^ ord(substr($hexzaehler,3,1)));

549	#printf ("\$hwert = substr\(\$wert,7,4\);\n\n");

550	printf ("\$Fehlerpufferdaten[2] = substr\(\$wert,7,4\);\n\n");

551	$zaehler++;

552	$hexzaehler= sprintf ("%4X",$zaehler);

553	printf ("Einlesen\(\"\\0020053??%04X\\003\\x%02X\"\)\n",$zaehler, 7^ ord(substr($hexzaehler,0,1)) ^ ord(substr($hexzaehler,1,1)) ^ ord(substr($hexzaehler,2,1)) ^ ord(substr($hexzaehler,3,1)));

554	printf ("\$Fehlerpufferdaten[3] = substr\(\$wert,7,4\);\n\n");

555	$zaehler++;

556	$hexzaehler= sprintf ("%4X",$zaehler);

557	printf ("Einlesen\(\"\\0020053??%04X\\003\\x%02X\"\)\n",$zaehler, 7^ ord(substr($hexzaehler,0,1)) ^ ord(substr($hexzaehler,1,1)) ^ ord(substr($hexzaehler,2,1)) ^ ord(substr($hexzaehler,3,1)));

558	printf ("\$Fehlerpufferdaten[4] = substr\(\$wert,7,4\);\n\n");

559	$zaehler++;

560	$hexzaehler= sprintf ("%4X",$zaehler);

561	printf ("Einlesen\(\"\\0020053??%04X\\003\\x%02X\"\)\n",$zaehler, 7^ ord(substr($hexzaehler,0,1)) ^ ord(substr($hexzaehler,1,1)) ^ ord(substr($hexzaehler,2,1)) ^ ord(substr($hexzaehler,3,1)));

562	printf ("\$Fehlerpufferdaten[5] = substr\(\$wert,7,4\);\n\n");

563	$zaehler++;

564	$hexzaehler= sprintf ("%4X",$zaehler);

565	printf ("Einlesen\(\"\\0020053??%04X\\003\\x%02X\"\)\n",$zaehler, 7^ ord(substr($hexzaehler,0,1)) ^ ord(substr($hexzaehler,1,1)) ^ ord(substr($hexzaehler,2,1)) ^ ord(substr($hexzaehler,3,1)));

566	printf ("\$Fehlerpufferdaten[6] = substr\(\$wert,7,4\);\n\n");

567	printf ("Fehlerpufereintrag $laufzahl: %2s.%2s.%4s %2s:%2s:%2s - Fehlerstatus %2X\n",$Fehlerpufferdaten[0],$Fehlerpufferdaten[1],$Fehlerpufferdaten[2],$Fehlerpufferdaten[3],$Fehlerpufferdaten[4],$Fehlerpufferdaten[5],$Fehlerpufferdaten[6]);

568	$zaehler++;

569	$laufzahl++;

570	ausgang();

571	}#dofehlerpuffer

572

573	sub fehlerpuffertest {

574	##

575	# tut noch nicht...

576	##

577	initialisierung(0);

578	Einlesen("\0020053??C000\003\x74");

579	$Fehlerpufferdaten[0] = substr($wert,7,4);

580	Einlesen("\0020053??C001\003\x75");

581	$Fehlerpufferdaten[1] = substr($wert,7,4);

582	Einlesen("\0020053??C002\003\x76");

583	$Fehlerpufferdaten[2] = substr($wert,7,4);

584	Einlesen("\0020053??C003\003\x77");

585	$Fehlerpufferdaten[3] = substr($wert,7,4);

586	Einlesen("\0020053??C004\003\x70");

587	$Fehlerpufferdaten[4] = substr($wert,7,4);

588	Einlesen("\0020053??C005\003\x71");

589	$Fehlerpufferdaten[5] = substr($wert,7,4);

590	Einlesen("\0020053??C006\003\x72");

591	$Fehlerpufferdaten[6] = substr($wert,7,4);

592	printf ("Fehlerpufereintrag $laufzahl: %2s.%2s.%4s %2s:%2s:%2s - Fehlerstatus %2X\n",$Fehlerpufferdaten[0],$Fehlerpufferdaten[1],$Fehlerpufferdaten[2],$Fehlerpufferdaten[3],$Fehlerpufferdaten[4],$Fehlerpufferdaten[5],$Fehlerpufferdaten[6]);

593	undef $ob;

594	}#fehlerpuffertest

595	exit;