Knowledge Base Nr: 00182 zeitschaltuhr.cpp - http://www.swe-kaiser.de

Win32: MFC: Zeitschaltuhr für Kinder-PC über Web-Interface und RS232.

  
//Kleines Programm auf dem Server (Taskbar) das den Zugriff auf den Kinder-PC steuert.
//Die Benutzungszeit kann über das Internet/Intranet im Browser eingestellt werden.
//Eine Leuchtdiode am Kinder-PC warnt rechtzeitig vor der Sperre damit der PC kontrolliert heruntergefahren werden kann.
//FTPSOURCE:cpp_classes.zip#Basisklassen

######################################################
### Hardware Interface

RS232 -> Pin3 TxD (rot) LED mit 470 Ohm Vorwiderstand an Pin5 GND (grün).
Pin4 DTR (rosa) direkt an Solid State Relais für 220V/8A.

9pol.DSub-Stecker:
------------------
Ausgänge PC->Rest der Welt:
Pin 3 TxD
Pin 4 DTR
Pin 7 RTS

Eingänge Rest der Welt->PC:
Pin 1 CD
Pin 2 RxD
Pin 6 DSR
Pin 8 CTS
Pin 9 RI

Pin 5 GND

TxD kann direkt mit Write() geschrieben werden
Eingänge mit GetCommModemStatus() lesen
Ausgänge mit EscapeCommFunction schreiben

######################################################
### PHP Teil

...

<html>
<head>
<title>Zeitschaltuhr</title>
</head>

<body>
<h1>Zeitschaltuhr für Kinder-PC</h1>

<p> Hier kann der Kinder-PC freigeschaltet werden. Das funktioniert natürlich nur auf unserem Server daheim.
Soll der PC beispielsweise am 15:00 Uhr 2 Stunden lang freigeschaltet sein ist von '15:00' bis '17:00'
einzugeben.</p>
<center><a href="/kaiserreich/k_zeitschaltuhr.php3">Refresh</a></center>
<p>

<?
if (!$from) #zeiten auslesen und default-zeiten setzen
{
$cmd = "e:/mystuff/zeitschaltuhr.exe status=1";
system(escapeshellcmd($cmd));

$data = file("c:/temp/zeitschalt.tmp");
$arr = split("-", $data[0]);

$from = $arr[0];
$to = $arr[1];
#echo("<h2>.$data.$from.$to.</h2>");
}
else
{
$cmd = "e:/mystuff/zeitschaltuhr.exe ein=$from aus=$to";
system(escapeshellcmd($cmd));
#echo("<h2>.$data.$from.$to.$cmd</h2>");
}
?>

<form action="/kaiserreich/k_zeitschaltuhr.php3" method="get">
Freischalten von
<select name="from" size="1">
<option SELECTED><? echo($from); ?></option>
<option>08:00</option>
<option>09:00</option>
...
<option>21:00</option>
<option>22:00</option>
</select>
Uhr bis
<select name="to" size="1">
<option SELECTED><? echo($to); ?></option>
<option>08:00</option>
<option>09:00</option>
...
<option>21:00</option>
<option>22:00</option>
</select>
Uhr.
<input name=""type="submit" value="Übernehmen">

<p>

<p> Eine Leuchtdiode am Kinder-PC warnt rechtzeitig vor der Sperre.</p>

</form>

</body>
</html>

######################################################
### C++ Teil

...

#include "../cpp_classes/DataExchange.h"
#include "../cpp_classes/ProcessSupport.h"
#include "../cpp_classes/SerialCom.h"
#include "../cpp_classes/TaskbarSupport.h"

...

const char* STATUSFILE = "c:/temp/zeitschalt.tmp";
const char* PORT = "COM4";

CMyDataExchange g_dataex("zeitschaltuhr");
char g_szData[12] = {0};

CSerialCom* g_pser = 0;

CTaskbarSupport* g_pTB = 0;

...

BOOL CZeitschaltuhrDlg::OnInitDialog()
{
...

CString strStatus = CProcessSupport::GetCommandlineParam("status");
CString strEin = CProcessSupport::GetCommandlineParam("ein");
CString strAus = CProcessSupport::GetCommandlineParam("aus");

//status holen
if (!strStatus.IsEmpty())
{
int nErr = g_dataex.Read(g_szData, sizeof(g_szData));
ASSERT(nErr == 0);

FILE* fp = fopen(STATUSFILE, "w+t");
ASSERT(fp);
if (fp)
{
fprintf(fp, "%s\n", g_szData);
fclose(fp);
}

PostQuitMessage(0);
}

//zeiten setzen
if (!strEin.IsEmpty() && !strAus.IsEmpty())
{
ASSERT(strEin.GetLength() == 5);
ASSERT(strAus.GetLength() == 5);

strncpy(g_szData, strEin, 5);
strcat(g_szData, "-");
strncat(g_szData, strAus, 5);
int nErr = g_dataex.Write(g_szData, sizeof(g_szData));
ASSERT(nErr == 0);

FILE* fp = fopen(STATUSFILE, "w+t");
ASSERT(fp);
if (fp)
{
fprintf(fp, "%s\n", g_szData);
fclose(fp);
}

PostQuitMessage(0);
}

//ohne parameter gestartet: status aus file lesen
if (strStatus.IsEmpty() && strEin.IsEmpty() && strAus.IsEmpty())
{
FILE* fp = fopen(STATUSFILE, "r+t");
ASSERT(fp);
if (fp)
{
fgets(g_szData, sizeof(g_szData), fp);
fclose(fp);

int nErr = g_dataex.Write(g_szData, sizeof(g_szData));
ASSERT(nErr == 0);
}
}

g_pser = new CSerialCom(0, PORT, 110, 'N', 8, 1, 'N'); //wichtig: hardware-handshake aus!
if (g_pser)
g_pser->Init();

g_pTB = new CTaskbarSupport(this, false);

HINSTANCE hinst = AfxGetInstanceHandle();
g_pTB->AddState(hinst, IDI_ICON_EIN, 0, "Zeitschaltuhr ein");
g_pTB->AddState(hinst, IDI_ICON_AUS, 1, "Zeitschaltuhr aus");

SetTimer(0, 1000, NULL);

return TRUE; // return TRUE unless you set the focus to a control
}

...

void CZeitschaltuhrDlg::OnTimer(UINT nIDEvent)
{
static bool s_bFirst = true;
if (s_bFirst)
{
g_pTB->Hide(); //in oninitdialog() nutzts leider nix - irgendwas setzt es zurück - also hier versuchen
s_bFirst = false;
}

static bool s_bLocked = false;
if (!s_bLocked)
{
s_bLocked = true;

ZeroMemory(g_szData, sizeof(g_szData));
int nErr = g_dataex.Read(g_szData, sizeof(g_szData));
ASSERT(nErr == 0);

GetDlgItem(IDC_STATUS)->SetWindowText(g_szData);

bool bEin = false;
bool bWarnung = false;

if (IsDlgButtonChecked(IDC_CHECK))
{
bEin = true;
}
else
{
CTime now(CTime::GetCurrentTime());
int nHourStart, nMinStart;
int nHourEnd, nMinEnd;

int n = sscanf(g_szData, "%d:%d-%d:%d", &nHourStart, &nMinStart, &nHourEnd, &nMinEnd);
if (n == 4)
{
CTime start(now.GetYear(), now.GetMonth(), now.GetDay(), nHourStart, nMinStart, 0);
CTime end(now.GetYear(), now.GetMonth(), now.GetDay(), nHourEnd, nMinEnd, 0);

if (now>=start)
{
if (now<=end)
bEin = true;
}

CTime warn(now + CTimeSpan(0, 0, 5, 0));

if (warn>=end && bEin)
bWarnung = true;
}
}

if (g_pser)
{
nErr = g_pser->SetDTR(bEin);
ASSERT(nErr == 0);

if (bWarnung)
{
char szData[] = "The quick brown fox jumps over the laszy dog";
nErr = g_pser->Write(szData, strlen(szData));
ASSERT(nErr == 0);
}
}

if (g_pTB)
{
if (bEin)
g_pTB->SetState(0, "Zeitschaltuhr ein");
else
g_pTB->SetState(1, "Zeitschaltuhr aus");
}

s_bLocked = false;
}

CDialog::OnTimer(nIDEvent);
}