Sample code for the TrainInfoLib

Dependencies:   NJE10XCtrlLib NTPClient_NetServices mbed IniFileLib NextTrainFileLib TrainInfoLib lwip

Revision:
0:1a9fa43d77af
Child:
1:93b052511e2c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TrainInfoSample.cpp	Fri Nov 19 20:40:48 2010 +0000
@@ -0,0 +1,353 @@
+///////////////////////////////////////////////////////////////////////////////
+// TrainInfo: sample code for the TrainInfo library   by rinos 2010
+///////////////////////////////////////////////////////////////////////////////
+
+#include "TrainInfo.h"
+#include "NJE10XCtrl.h"
+#include <time.h>
+
+///////////////////////////////////////////////////////////////////////////////
+
+LocalFileSystem local("local");
+NJE10XCtrl gNJE(p9);
+
+// critical section
+#define TickerLock()   (NVIC_DisableIRQ(TIMER3_IRQn))
+#define TickerUnlock() (NVIC_EnableIRQ (TIMER3_IRQn))
+
+// Config file
+#ifndef ROOTPATH
+#define ROOTPATH	"/local/"
+#endif
+const char INI_FILE[]			= ROOTPATH "TInfo.ini";
+const int DEFAULT_GIVEUP_SEC	= 30; // Giveup-seconds to take the next train
+int  gGiveupSec = DEFAULT_GIVEUP_SEC;
+char gDelayMessage[TrainInfo::MAX_DELAY_MESSAGE];
+int  gDispMode = 0;
+int gTimeZone = 540; // +9h00m
+
+// Latest search cache
+time_t gSerchTime;
+NextTrainFile::NextInfo gNext[2];
+int  gDelayStatus = 0;
+const int S_INFO_OK	= 0x01;
+const int S_DELAY	= 0x10;
+
+
+////////////////////////////////////////////////////////////////////////////////
+// RTC Configuration
+
+//#define USE_NTPCLIENT 1
+
+#ifdef USE_NTPCLIENT
+#include "EthernetNetIf.h"
+#include "NTPClient.h"
+
+int UpdateRTC(const char* ntp_server, int ntp_port, int timezone) {
+    printf("UpdateRTC by NTPClient...\n");
+
+	EthernetNetIf eth;
+    EthernetErr ethErr = eth.setup(); // default timeout: 15sec
+    if (ethErr) {
+        printf("eth.setup failed %d.\n", ethErr);
+        return 1;
+    }
+/*
+	time_t now = time(0);
+	if(now){
+		printf("Use current RTC: %d\n", now);
+		return 0;
+	}
+*/
+    printf("Connect to the NTP server %s...\n", ntp_server);
+
+	NTPResult ntpErr = NTPClient().setTime(Host(IpAddr(), ntp_port, ntp_server));
+	if(ntpErr){
+        printf("NTPClient::setTime failed %d.\n", ntpErr);
+        return 2;
+	}
+
+#else
+// I can't use NTPClient with LWIP HTTPClient...
+// So, I get the RTC via http-NTP server.
+
+#include "HTTPClient.h"
+#define NTP2POSIX 2208988800UL
+
+int UpdateRTC(const char* ntp_server, int ntp_port, int timezone) {
+    printf("UpdateRTC by HTTP-NTP...\n");
+
+	char rbuf[80];
+    printf("Connect to the NTP server %s...\n", ntp_server);
+	HTTPClient http;
+	http.timeout(10);
+    int len = http.get(ntp_server, rbuf, sizeof(rbuf) - 1);
+	if(len){
+		rbuf[len] = '\0';
+		char* p = strstr(rbuf, "<BODY>");
+		if(p){
+			p += 7;
+			time_t val = strtoul(p, 0, 10) - NTP2POSIX;
+			set_time(val);
+			printf("NTP set %d\n", val);
+		}
+    	printf("HTTPClient download [%s]\n", rbuf);
+	}
+
+#endif
+	// Puts RTC (JST)
+	time_t now = time(0) + timezone;
+    printf("RTC(JST): %s\n", ctime(&now));
+    return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Display control
+
+#include "NJE10XCtrl.h"
+
+char gMsgNoTrain[100] = "NoTrain";
+char gMsgLeft	[ 20] = "Left";
+char gMsgDir	[ 20] = "To";
+char gMsgSec	[ 20] = "Sec";
+int  gMsgWarn = 60 * 3; // 3min
+
+void dispTime(){
+	char buf[100];
+	time_t t = time(0) + gTimeZone;
+	struct tm* st = localtime(&t);
+	t -= gSerchTime;
+
+	gNJE.clear();
+	NextTrainFile::NextInfo* p = &gNext[0];
+	if(p->m_diff < 0){
+		printf("Now:%02d:%02d:%02d, %s\n", st->tm_hour, st->tm_min, st->tm_sec, gMsgNoTrain); // or error
+		sprintf(buf, "%02d:%02d:%02d ", st->tm_hour, st->tm_min, st->tm_sec);
+		gNJE.add(buf);
+		gNJE.addAttr(NJE10XCtrl::ATTR_RED);
+		gNJE.add(gMsgNoTrain);
+		gNJE.setMessage(1);
+		return;
+	}
+
+	// Check the difference (was gone?)
+	int diff = p->m_diff - t;
+	if(diff < gGiveupSec){
+		p = &gNext[1];
+		diff = p->m_diff - t;
+	}
+
+	// Show message to the NJE-105
+	NJE10XCtrl::Attr1 a1 = NJE10XCtrl::ATTR_GREEN;
+	NJE10XCtrl::Attr2 a2 = NJE10XCtrl::ATTR_SCROLL_R;
+	NJE10XCtrl::Attr3 a3 = NJE10XCtrl::ATTR_NORMAL;
+
+	if(diff < 0){
+		printf("%02d:%02d Gone%2dsec ", p->m_hour, p->m_min, -diff);
+
+		sprintf(buf, "%02d:%02d", p->m_hour, p->m_min);
+		gNJE.add(buf);
+		//gNJE.addAttr(NJE10XCtrl::ATTR_YELLOW, NJE10XCtrl::ATTR_SCROLL);
+		gNJE.add(p->m_option);
+		gNJE.add(gMsgDir);
+		sprintf(buf, " Gone%ds", -diff);
+		gNJE.add(buf);
+	} else if(diff < 60) {
+		// 123456789012345678901234 (NJE-105)
+		// MM:HH •’Ê “ú‹gs Žc59•b
+		printf("%02d:%02d Left%2dsec %s\n", p->m_hour, p->m_min, diff, p->m_option);
+
+		sprintf(buf, "%02d:%02d", p->m_hour, p->m_min);
+		gNJE.add(buf);
+		gNJE.addAttr(NJE10XCtrl::ATTR_YELLOW, NJE10XCtrl::ATTR_SCROLL_R);
+		gNJE.add(p->m_option);
+		gNJE.add(gMsgDir);
+		gNJE.addAttr((diff<gMsgWarn)? NJE10XCtrl::ATTR_RED : NJE10XCtrl::ATTR_GREEN, NJE10XCtrl::ATTR_SCROLL_R);
+		gNJE.add(' ');
+		gNJE.add(gMsgLeft);
+		sprintf(buf, "%2d%s", diff, gMsgSec);
+		gNJE.add(buf);
+	} else {
+		// 123456789012345678901234 (NJE-105)
+		// MM:HH•’Ê “ú‹gs Žc01:23
+		int diff_min = diff / 60;
+		int diff_sec = diff % 60;
+		printf("%02d:%02d Left%2d:%02d(%s)\n", p->m_hour, p->m_min, diff_min, diff_sec, p->m_option);
+
+		sprintf(buf, "%02d:%02d", p->m_hour, p->m_min);
+		gNJE.add(buf);
+		gNJE.addAttr(NJE10XCtrl::ATTR_YELLOW, NJE10XCtrl::ATTR_SCROLL_R);
+		gNJE.add(p->m_option);
+		gNJE.add(gMsgDir);
+		gNJE.addAttr((diff<gMsgWarn)? NJE10XCtrl::ATTR_RED : NJE10XCtrl::ATTR_GREEN, NJE10XCtrl::ATTR_SCROLL_R);
+		gNJE.add(gMsgLeft);
+		sprintf(buf, "%2d:%02d", diff_min, diff_sec);
+		gNJE.add(buf);
+	}
+
+	// delay
+	a1 = NJE10XCtrl::ATTR_GREEN;
+	int delay = 0;
+	if(gDelayStatus & S_DELAY){
+		delay = 1;
+		a1 = NJE10XCtrl::ATTR_RED;
+	} else if(*gDelayMessage){
+		if(diff % 60 < 3) delay = 1;
+	}
+
+	if(delay) gNJE.setMessage(2, gDelayMessage, a1);
+	else      gNJE.delMessage(2);
+	gNJE.setMessage(1, 0, a1, a2, a3);
+
+//	if(delay) gNJE.setMessage(1, gDelayMessage);
+//	else      gNJE.setMessage(1, 0, a1, a2, a3);
+}
+
+void dispDelay(){
+	if(++gDispMode > 10) gDispMode = 0;
+	if(gDispMode != 1){
+		gNJE.delMessage(2);
+		return;
+	}
+	printf("%s\n", gDelayMessage);
+	gNJE.setMessage(2, gDelayMessage);
+}
+
+void dispWait(){
+	if(++gDispMode > 10) gDispMode = 0;
+	if(gDispMode != 1){
+		return;
+	}
+	printf("Please wait...\n");
+	gNJE.setMessage(1, "Please wait...");
+}
+
+void dispCB(){
+//	if(gDelayStatus & S_DELAY){
+//		dispDelay();
+//	} else {
+		if(gDelayStatus & S_INFO_OK){
+			dispTime();
+			gDispMode = 0;
+		} else {
+			dispWait();
+		}
+//	}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NextTrain & Delay information control
+int updateNext(TrainInfo& train){
+	printf("UpdateTrain\n");
+
+	// Next (and 2nd Next) train check
+	TickerLock();
+	time_t now = time(0) + gTimeZone;
+	gSerchTime = now;
+	struct tm* st = localtime(&now);
+	for(int index = 0, offset = 0 ; index < 2; ++offset){
+		NextTrainFile::Status ret = train.search(now, offset);
+		switch(ret){
+		case NextTrainFile::S_SUCCESS:
+			if(train.next()->m_diff > gGiveupSec){
+				gNext[index++] = *train.next();
+			}
+			break;
+
+		case NextTrainFile::S_NO_TRAIN:
+			gNext[index++].m_diff = -1;
+			break;
+
+		default:
+			gNext[index++].m_diff = -2;
+			break;
+		}
+	}
+	gDelayStatus |= S_INFO_OK;
+	TickerUnlock();
+	return 0;
+}
+
+int updateDelay(TrainInfo& train){
+	// Delay check
+	TrainInfo::Status ret = train.checkDelay();
+	if(ret == TrainInfo::S_DELAY_DETECTED){
+		TickerLock();
+		train.getDelayMessage(gDelayMessage, sizeof(gDelayMessage));
+		gDelayStatus |= S_DELAY;
+		TickerUnlock();
+	} else {
+		TickerLock();
+		train.getDelayMessage(gDelayMessage, sizeof(gDelayMessage)); // copy for testing...
+		gDelayStatus &= ~S_DELAY;
+		TickerUnlock();
+	}
+	return 0;
+}
+
+int updateAll(){
+	TrainInfo train;
+
+	if(train.open(INI_FILE)){
+		printf("Can't open INI file '%s'\n", INI_FILE);
+		return 1;
+	}
+	updateNext (train);
+	updateDelay(train);
+	return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Configuration and Startup
+int setupParams(const char* inifile){
+	char ntpserver[100] = "ntp.jst.mfeed.ad.jp";
+	int ntpport  = 123;
+
+	const IniFile::IniList INI_PARAM_LIST[] = {
+		INIFILE_INT("GiveupSec", gGiveupSec),
+		INIFILE_STR("NTPServer", ntpserver, sizeof(ntpserver)),
+		INIFILE_INT("NTPPort",   ntpport),
+		INIFILE_INT("TimeZone",  gTimeZone),
+
+		INIFILE_STR("MsgNoTrain",	gMsgNoTrain,	sizeof(gMsgNoTrain)),
+		INIFILE_STR("MsgLeft",		gMsgLeft,		sizeof(gMsgLeft)),
+		INIFILE_STR("MsgDir",		gMsgDir,		sizeof(gMsgDir)),
+		INIFILE_STR("MsgSec",		gMsgSec,		sizeof(gMsgSec)),
+		
+		INIFILE_INT("MsgWarn",		gMsgWarn),
+
+		INIFILE_END,
+	};
+
+	IniFile::getval(inifile, INI_PARAM_LIST);
+	gTimeZone *= 60;
+
+	// Init NJE
+	gNJE.setScrollSpeed(NJE10XCtrl::ScrollSpeed(NJE10XCtrl::SCROLL_FAST));
+    //gNJE.setBlinkSpeed(NJE10XCtrl::BlinkSpeed(NJE10XCtrl::BLINK_FAST));
+    gNJE.setStopTime(1);
+	gNJE.setMessage(1, "Please wait...");
+
+
+	// Init RTC	
+	UpdateRTC(ntpserver, ntpport, gTimeZone);
+	return 0;
+}
+
+int main(){
+	setupParams(INI_FILE);
+	Ticker dispTicker;
+	dispTicker.attach(dispCB, 1); // 1 update per sec
+
+	for(;;){
+		printf("Update information\n");
+		if(updateAll()) break;
+
+		// Free LocalFileSystem before waiting.
+		// (For access file via USB)
+		wait(60);
+	}
+	dispTicker.detach();
+	printf("Program end\n");
+	return 0;
+}