unit Unit1; interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, pegelUnit, fhUnit, lowLevelUnit; type { TForm1 } TForm1 = class(TForm) Image1: TImage; RegenSturmIco: TImage; RegenIco: TImage; SturmIco: TImage; SonneIco: TImage; WolkeIco: TImage; TrayIcon1: TTrayIcon; procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormShow(Sender: TObject); procedure TrayIcon1Click(Sender: TObject); procedure TrayIcon1DblClick(Sender: TObject); procedure TrayIcon1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X,Y: Integer); private { private declarations } datenZeitRaum: extended; pegel: tPegelStaende; wetter: tMessPunkte; pegelDatei,wetterDatei: string; lMB: tMouseButton; public { public declarations } procedure zeichnen; end; var Form1: tForm1; pidDatei: string; fehler: boolean; const bufLengMin = 1024*1024; (* function separateValue(var S: String): string; function Zeit2Datetime(Z: TZeit): extended; function PegelstaendeVergleichen(P1,P2: Pointer): integer; function PegelzeitVergleichen(P1,P2: TPegelzeit): integer; function findePegelZeit(PS: TList; PZ: TPegelzeit): extended; function strToPegelZeit(s: string): TPegelzeit; function Pegelzeit2Datetime(Z: TPegelzeit): extended; function letzterMonat(t: TDateTime): TPoint; // x=Monat, y=Jahr function MyIntToStr(I,Ziff: longint): string; *) function wertZuX(w: extended; startZeit,stopZeit: extended; breite: longint): longint; inline; function wertZuY(w: extended; miMa: tPoint; hoehe: longint): longint; inline; overload; function wertZuY(w: extended; miMa: tExtPoint; hoehe: longint): longint; inline; overload; function wertZuY(w: extended; mi,ma: extended; hoehe: longint): longint; inline; overload; procedure SignalCapture(signal : longint); cdecl; implementation {$R *.lfm} uses process, myStringListUnit, systemUnit, matheunit, math, baseUnix; { TForm1 } procedure TForm1.FormCreate(Sender: TObject); var s,t: string; f,o: tMyStringList; fi: textfile; args: array of string; na: pSigActionRec; begin fehler:=true; __ausgabenMaske:=1; lMB:=mbLeft; pidDatei:=''; pegelDatei:=''; datenZeitRaum:=1; s:=extractfilepath(application.exename)+'wetter.konf'; t:=''; if not fileexists(s) then raise exception.create('Kann Konfigurationsdatei '''+s+''' nicht finden!'); pegel:=tPegelStaende.create(image1); wetter:=tMessPunkte.create(image1); f:=tMyStringList.create; f.loadFromFile(s); f.unfoldMacros; while f.readln(s) do begin if startetMit('pidDatei:',s) then begin pidDatei:=s; assignFile(fi,pidDatei); if fileexists(pidDatei) then begin // pidDatei existiert schon reset(fi); readln(fi,s); if strtoint(s)<>GetProcessID then begin // der eingetragene Prozess bin nicht ich setlength(args,1); args[0]:='aux'; runCommand('ps',args,t); o:=tMyStringList.create; o.text:=t; o.grep('^\S+\s+'+s+'\s'); if o.count>0 then begin // der eingetragene Prozess läuft noch closeFile(fi); f.free; o.free; pegel.free; raise exception.create('Programm läuft bereits ('+s+')!'); end; o.free; end; closefile(fi); end; rewrite(fi); writeln(fi,inttostr(GetProcessID)); closeFile(fi); continue; end; if startetMit('pegelDatei:',s) then begin pegelDatei:=s; if pos('/',pegelDatei)=0 then pegelDatei:=extractFilePath(application.exename)+pegelDatei; pegel.laden(pegelDatei); continue; end; if startetMit('wetterDatei:',s) then begin wetterDatei:=s; if pos('/',wetterDatei)=0 then wetterDatei:=extractFilePath(application.exename)+wetterDatei; wetter.laden(wetterDatei); continue; end; if startetMit('datenZeitRaum:',s) then begin datenZeitRaum:=exprtofloat(false,s,nil,nil); continue; end; f.free; pegel.free; raise exception.create('Unbekannte Option '''+s+''' in Konfigdatei!'); end; f.free; new(na); na^.sa_Handler := sigActionHandler(@signalCapture); fillchar(na^.sa_Mask,sizeof(na^.sa_mask),#0); na^.sa_Flags := 0; {$ifdef Linux} // Linux specific na^.sa_Restorer := Nil; {$endif} if (fPSigaction(SIGUSR1, na, nil) <> 0) or (fPSigaction(SIGTERM, na, nil) <> 0) or (fPSigaction(SIGINT, na, nil) <> 0) then begin writeln('Fehler beim Signalempfängerreservieren: '+inttostr(fpgeterrno)+'.'); raise exception.create('Fehler beim Signalempfängerreservieren: '+inttostr(fpgeterrno)+'.'); end; dispose(na); zeichnen; fehler:=false; end; procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction); begin form1.visible:=false; trayIcon1.visible:=false; pegel.putBeenden; wetter.mutBeenden; end; procedure TForm1.FormDestroy(Sender: TObject); begin if fileExists(pidDatei) then deleteFile(pidDatei); if not fehler then begin if pegelDatei<>'' then pegel.speichern(pegelDatei); if wetterDatei<>'' then wetter.speichern(wetterDatei); end; pegel.free; wetter.free; end; procedure TForm1.FormShow(Sender: TObject); begin form1.top:= screen.monitors[0].top +screen.monitors[0].height-form1.height-24; form1.left:=screen.monitors[0].left+screen.monitors[0].width -form1.width; end; procedure TForm1.TrayIcon1Click(Sender: TObject); begin form1.visible:=not form1.visible; end; procedure TForm1.TrayIcon1DblClick(Sender: TObject); begin if (lMB=mbRight) or (messageDlg('Wetter wirklich beenden?',mtConfirmation,[mbYes,mbNo],0)=mrYes) then form1.close; end; procedure TForm1.TrayIcon1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X,Y: Integer); begin lMB:=button; end; procedure TForm1.zeichnen; var tmp,startZeit,stopZeit: extended; s: string; begin fehler:=true; image1.canvas.brush.color:=$ffffff; image1.canvas.rectangle(-10,-10,image1.width,image1.height); stopZeit:=now; startZeit:=stopZeit-datenZeitRaum; pegel.achsenZeichnen([psRudolstadt,psRothenstein],startZeit,stopZeit); wetter.achsenZeichnen([mgTemperatur],startZeit,stopZeit); image1.canvas.pen.color:=$000000; tmp:=floor(startZeit); while wertZuX(tmp,startZeit,stopZeit,Image1.Width) 0.25) or (byte(wetter.maxWind > 2.5)*2) or (byte(wetter.gesRegen > 0)*4) of $00: trayIcon1.Icon:=WolkeIco.Picture.Icon; $01: trayIcon1.Icon:=SonneIco.Picture.Icon; $02,$03: trayIcon1.Icon:=SturmIco.Picture.Icon; $04,$05: trayIcon1.Icon:=RegenIco.Picture.Icon; $06,$07: trayIcon1.Icon:=RegenSturmIco.Picture.Icon; end{of Case}; s:=wetter.hintInfo+' '+pegel.hintInfo; image1.canvas.font.color:=$000000; image1.canvas.textOut((image1.width-image1.canvas.textWidth(s)) div 2,1,s); s[pos(',',s)-3]:=#13; s[pos('%',s)+1]:=#13; s:=s+wetter.mehrInfos([mgTemperatur,mgLuftfeuchte,mgWindgeschwindigkeit,//mgWindrichtung, mgNiederschlag,//mgGlobalstrahlung, mgLuftdruck]); trayIcon1.hint:=s; trayIcon1.visible:=true; fehler:=false; end; // allgemeine Funktionen ******************************************************* function wertZuX(w: extended; startZeit,stopZeit: extended; breite: longint): longint; const xScale = 3.132265450540420106833422460869303332478; // xScale / (e^xScale - 1) = 1/7 var tmp: extended; begin tmp:=(w-startZeit)/(stopZeit-startZeit); result:=1+round(-(breite-2)*ln(1+tmp*(exp(-xScale)-1))/xScale); end; function wertZuY(w: extended; miMa: tPoint; hoehe: longint): longint; begin result:=wertZuY(w,miMa.x,miMa.y,hoehe); end; function wertZuY(w: extended; miMa: tExtPoint; hoehe: longint): longint; begin result:=wertZuY(w,miMa['x'],miMa['y'],hoehe); end; function wertZuY(w: extended; mi,ma: extended; hoehe: longint): longint; begin result:=hoehe-1-round((w-mi)/(ma-mi)*(hoehe-2)); end; procedure SignalCapture(signal : longint); cdecl; begin case signal of SIGUSR1: begin writeln('received SIGUSR1!'); if assigned(form1.pegel) and (form1.pegelDatei<>'') then form1.pegel.speichern(form1.pegelDatei); if assigned(form1.wetter) and (form1.wetterDatei<>'') then form1.wetter.speichern(form1.wetterDatei); end; SIGTERM,SIGINT: begin writeln('received SIGTERM/SIGINT!'); form1.close; end; end{of case}; end; end.