HTML och CGI eller?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46930
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

HTML och CGI eller?

Inlägg av TomasL »

HTML och CGI är inte riktigt min starka sida i nuläget.

I projektet jag håller på med behöver jag visa dynamiska data på en html-sida.
Det vanligste och "enklaste " sättet är tydligen att använda cgi.

Mitt problem, jag har upp tiill nått tusental olika data som vid behov och val skall kunna visas.
Detta innebär, om jag fattat saken rätt att jag måste lägga inkludera samma antal cgi-variabler i mitt program.

Finns det nått enklare sätt att göra detta på, tänke jag skulle slippa en switch-sats med typ 1200 "cases" eller så (det gör jag förmodligen inte, när jag tänker efter). men vilka alternativ finns det för att infoga dynamiska data?
Användarvisningsbild
oJsan
EF Sponsor
Inlägg: 1541
Blev medlem: 11 november 2005, 21:36:51
Ort: Umeå
Kontakt:

Inlägg av oJsan »

Hur är ditt data lagrat? I en databas eller hämtas det i realtid via någon typ av socket?
Ett sätt vore att dela upp ditt projekt i två delar. En program som samlar in data och lagrar de x senaste mätvärdena i en databas.
Sedan skriver du en webapplikation som presenterar data ur databasen. Jag skulle rösta på php, om du möjligtvis kan mer om det än HTML/CGI. Vad menar du förresten med "dynamiska data"? En parameter som kan anta mer än bara ett enda värde? :) Eller menar du att data ska visas i realtid på en HTML-sida?
Jag tror att de här graferna är genererade med ett php-bibliotek.. är det så du menar?

Edit: förresten, var kommer mikroprocessorn in i bilden?
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46930
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Inlägg av TomasL »

Hmm, var nog lite otydlig.
Det handlar i princip om att visa data i realtid, med realtid menar jag att data uppdateras varannan sekund eller så.

Webservern är PIC-baserad, så php och dyligt är inte tillgängligt.
Vissa data ligger redan lagrade som variabler i programmet, medan andra data hämtas vid behov från div kringenheter


Edit till mitt första inlägg, vad jag menade var en kombination av CGI och SSI.

Alla data visas dock inte samtidigt utan är beroend på vilken html-sida som visas och vilka data som valts att visas vid skapandet av html-sidan.

Enkelt uttryckt med ett exempel:
Jag har upp till 31st Danfoss VLTer upphakade på en rs485 lina, grundata, redan lagrat i PICen är status bör och ärvärden för respektive omformare.

Dock skall man om man vill kunna se andra data från omformaren, till exemp aktuell motoreffekt, motoremperatur motorström etc.
Summa summarum blir det 16 olika data från varje omformare.
min urspungliga ide var att göra en #define för var och en av datapunkterna, men tyckte att det var en "klumpig" ide.
Nästa ide är att dela upp det hela och använda två ssi, en för omformarens address och en för datapunkten.

Datapunkterna i omformaren beskrivs som en 3-siffrig address, dvs 520 för motorström till exempel.
Så om jag då i html-sidan infogar en ssi tillexempel %101520, och låter programmet splitta upp detta till 101 och 520 för att komma åt omformare 1 funktion 520.

Nu har jag dock inte enbart data från externa enheter utan en del hämtas från AD och en del är beräknade. totalt blir det nått tusental olika datapunkter som kan visas.
Men finns det bättre alternativ?
Användarvisningsbild
oJsan
EF Sponsor
Inlägg: 1541
Blev medlem: 11 november 2005, 21:36:51
Ort: Umeå
Kontakt:

Inlägg av oJsan »

Ännu mer info skulle nog vara värdefullt...
Vad är det för webserver? Klarar den SSI och CGI? Hur många klienter kommer att ansluta? Låt säga att en html-sida på servern innehåller "%101520", var finns programvaran för att byta ut det mot rätt mätvärde? Är det ett SSI-plugin av något slag?
Att uppdatera varannan sekund.. är det något som användaren själv ska göra eller räcker det allt ladda om sidan med javascript?
Enklast hade nog varit om pic:en kontinuerligt skickar data till en databas någonstans på nätverket och att sedan bygga en separat applikation för visning, i en 'normal' miljö där det finns fler verktyg tillgängliga (generering av grafer och kanske lite ajax...)
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46930
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Inlägg av TomasL »

Nja, hela nätverket är uC/PIC-baserat, webservern och alla applikationer/programvara ligger direkt i resp PIC, dvs de hanterar allt inklusive web-sidorna.
Web-servern i PICen kan hantera både SSI och CGI, dock med ett reducerat antal kommandon.

Har kikat lite på dhtml, men det verkar bara stöda listor, typ, dessutom verkar dhtml vara olika implementerat i olika web-läsare, vilket uppenbarligen skapar problem (olika kommandon osv).
Uppdateringen är tänkt mha bl.a meta-refresh, då nya värden hämtas.

Kan nog använda dhtml vid visning av loggar och dyligt, eftersom de ändå kommer att sparas ned på CF/Disk i csv av PICen.
sodjan
EF Sponsor
Inlägg: 43247
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

CGI används för att skicka data *från* browsern *till* servern.
Om du enbart ska skicka data *till* browsern, så behöver inte CGI.
Om du däremot vill skicka en parameter (t.ex som "..../sida?param")
så kan man använda CGI för att "läsa" det som står efter "?" i URL'en.

Förtydliga.
Hur väljs vad som ska visas ?

> totalt blir det nått tusental olika datapunkter som kan visas.

Samtidigt !? På samma sida ?
Och det är väl inte "nått tusental datapunkter" som ska skickas *från* browsern ?
I alla fall inte på samma gång ?

> Web-servern i PICen kan hantera både SSI och CGI, dock med ett reducerat antal kommandon.

Dokumentation ?
Länk?

EDIT : Rättade ett till/från fel i andra meningen...
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46930
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Inlägg av TomasL »

NEJ, inte alla datapunkter på samma gång (trodde jag skrev det) nåväl.

I min PIC-applikation skall jag ha möjlighet att på varje webb-sida göra ett urval av de 1500 olika data som finns tillgängliga.
Om jag till exempel öppnar en HTML-sida som beskriver frekvensomformare x, så skall de 16 olika data som jag gjort tillgängliga visas, om det är är inlagt i HTML koden.

Jo jag vet att CGI används för att skicka data från browsern till servern, eftersom jag skall kunna ändra på inställningar i t.ex. frekvensomformaren så behöver jag det också.

Beträffande webservern så har jag skrivit den själv, följdaktligen finns ingen publicerbar dokumentation eller länkar.

Den fanns online via en länk här på forumet i vintras.
sodjan
EF Sponsor
Inlägg: 43247
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

OK.
Men då är det ju inte "ett tusental CGI variabler" som det handlar om.
Och i princip är det riktigt intressanta hur många det är på samma gång,
vid samma anrop.

Sedan så är det väl bara för din kod i din server att avkoda det som står
efter "?" och göra det som måste göras.

Jag måste ha missat något, men vad är igentligen frågan ?

Är det inte bara att skicka tillbaka en HTML sida med rellevanta
variabler inkluderade ?

Är det *lagringen* av 1000 mätvärden som är problemet ?
Finns alla 1000 mätvärden samtidigt eller skapas de dynamiskt
i samband med att HTML sidan skapas ?

> Om jag till exempel öppnar en HTML-sida som beskriver frekvensomformare x

Sker det med en egen unik URL för varje omf, eller en det en
gemensam URL med en "?omf=x" parameter ?
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46930
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Inlägg av TomasL »

Frågan var väl att om det fanns någon annan metod som var enklare än ssi, för att överföra mätvärden, då jag i princip måste generera 1500 unika konstanter för att kunna avkoda sidan.

Iofs om det kan fungera med att dela upp ssi varibeln i två delar med address och index, kanske det går lite enklare.

Dock blir det en tuff dokummentation att beskriva alla 1500 möjliga ssi-variabler, gissar jag.

Lagringen kan också bli ett problem som jag måste komma förbi.
Gissar att jag får stoppa in ett statiskt ram-minne på en bunt kB för att casha data.

Har dock inte hittat några seriella statiska RAMar, så det blir antagligen multiplex på 2 portar (hmm, börjar få ont om IO nu).
sodjan
EF Sponsor
Inlägg: 43247
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Hm...

Antag att du vill visa ca 16 olika värden för en av 31 olika omformare.

Browsern skickar en URL med en parameter som betyder "omformar-nummer".

Servern skapar en sida (*samma* sida för alla 31!) och stoppar
in de 16 värden som är rellevanta för den aktuella omformaren.

För *browsern* ser denna sida ut som vilken statisk HTML sida som helst.
D.v.s att browsern vet inte hur servern gjorde för att skapa sidan.

Sen är det en helt annan sak var de 16 värderna kommer från.
De kan ju vara så att de redan finns innan browsern begär sidan, men
det kan även skapas dynamiskt vid själva anropet och kräver alltså
inget permanent lagringsutrymme. Om de inte behövs till något annat
så klart, men det är lite av en annan fråga...

Men, och det är det viktiga, för *browsern* finns det alltså bara
16 olika variabler/datapunkter, inte 16x31 variabler. Vilken omformare
som för tillfället visas kan hanteras med en "hidden" variabel eller
liknande.

En annan sak är ju också att formatet som de 16 variablerna lagras på
antagligen ine alls är samma format som du vill ha det presenterat på,
så en del "knådande" av variablerna lär det bli i alla fall.

SSI vet jag inte vad det är, men det är säkert något bra...
Kaggen
Inlägg: 432
Blev medlem: 29 januari 2005, 03:06:02

Inlägg av Kaggen »

CGI = Common Gateway Interface.

Ofta ett program/skript som "triggas" av webservern och genererar HTML-kod "on-the-fly" som skrivs/print:as till STDIO (Standard I/O typ PRINT i BASIC) vilket webservern "redirectar" till aktuell browser.

Ett typisk CGI-skript/program i psuedo-kod ser ut ung. :

Kod: Markera allt

10 PRINT "<HTML>"
20 PRINT "<BODY>"
30 PRINT "<H1>Mitt fina CGI-skript</H1>"
40 FOR I = 1 TO 3
50 PRINT "Värdet I = ";I;"<BR>"
60 NEXT I
70 PRINT "</BODY>"
80 PRINT "</HTML>"
SSI = Server Side Includes (om det nu är denna förkortning du talar om). Det är ungefär detsamma som #include i Assembler eller C. Du inkluderar helt enkelt en HTML-fil i en annan HTML fil. Används ofta i statisk HTML för att göra sidhuvuden och sidfötter som skall se lika ut på flera websidor. Ändrar du i HTML-filen för sidhuvudet så ändras sidhuvudet i alla HTML filer som har den filen inkluderad.

DHTML = Dynamisk HTML. Består ofta av Javascript som exekveras på webklienten (i webbrowsern) och inte på servern. Används för att i fall där det är möjligt avlasta servern från onödig belastning vid t.ex. felkontroll av formulär m.m. Man får dock tänka på att Javascript som exekveras i webläsaren inte har full tillgång till webklientens dator av säkerhetsskäl. Du kan t.ex. inte spara eller öppna filer på klient-datorn o.s.v.


Jag antar att CGI är det du bör använda dig av, Du lägger förslagsvis upp ett CGI-skript/applikation (eller hur det nu fungerar i din PIC) för varje individuell sida du skall visa. Du kan ju själv ha egna koder för de HTML taggar du skall använda för att spara minne. 0x07 kan t.ex. vara BODY-taggen o.s.v. Eller helt enkelt använda index i en lång textsträng som består av alla nödvändiga taggar.

Edit: Vad är det för språk webserverns CGI-interface stödjer i PIC:en? Antar att det enbart är assembler? Eller är det något eget skriptliknande hopkok?
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46930
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Inlägg av TomasL »

Har inte komit tillcgi delen än, håller på med ssi'n för tillfället.

Så här gör jag:
Bakgrund, på de websidor som min pic-baserade server skall kunna skicka måste jag ha möjligheten att inkludera realtidsdata samt beräknade processdata, totalt rör det sig om nånstans mellan 1500 och 2000 olika variabler.
Det största flertalet av dessa kommer från externa enheter som bl.a. hänger på en RS 485-lina.

I min html kod använder jag % som esc-char, följd av en 6-siffrig kod, unik för varje enskilld variabel.
MSD är ett index som talar om vilken grundfunktion jag vill hämta från, t.ex. 2 betyder att jag skall hämta data från nån frekvensomformare, de nästa två siffrorna är en address, så 202 betyder frekvensomformaren med addressen 02, de sista 3 siffrorna är kommandot som skall utföras, ex-vis betyder det i detta fallet med frekvensomformaren 520 att jag vill ha motorströmmen.

Summa sumarum, om jag skriver %102520 i htmlkoden så skall min applikation/servern gå till frekvensomformaren (1) på adress 02 och hämta motorströmmen (520).

I nuläget har det blivit en gigantisk switch-sats, troligen kommer inte det att fungera, pga. begränsningar i relativ addressering hos PICarna. Men den tiden den sorgen.
Användarvisningsbild
oJsan
EF Sponsor
Inlägg: 1541
Blev medlem: 11 november 2005, 21:36:51
Ort: Umeå
Kontakt:

Inlägg av oJsan »

Om jag förstår dig rätt så har det här inte så mycket att göra med varken CGI, SSI eller HTML utan snarare om att placera mätvärden i en adressrymd va?!

Summa sumarum, om jag skriver %102520 i htmlkoden så skall min applikation/servern gå till frekvensomformaren (1) på adress 02 och hämta motorströmmen (520).
Vad menar du med "gå till"? Jag antar att det är här skon klämmer... Vet inte så mycket om SSI, men jag gissar att den bara gör include på redan existerande data (såsom filer). Fördelen med CGI är ju att saker kan genereras dynamiskt. Här nedan finns en liten kodsnutt som borde bespara dig många switch-case om den implementeras i form av CGI (var har du föresten din gigantiska switch-case i nuläget?):

Kod: Markera allt

char* SSI_string = "102520"; //Indata
u16 type_of_unit;	//typ av enhet
u16 address;	//Enhetens adress
u16 parameter;	//Parameter att avläsa

u16 retvalue; //returvärde att skriva ut på sidan (efter viss formatering)

//Parsa ut de olika delarna och omvandla från char-sträng till integers:
parse_six_digit_code(SSI_string, &type_of_unit, &address, &parameter);
//De tre variablerna innehåller nu rätt värde...

switch(type_of_unit)
{
	case FREKVENSOMVANDLARE:
		retval = get_frekvensomvandlarparamter(address, parameter);
		break;

	case TEMPGIVARE:
		retval = get_tempvalue(address);
		break;
	default:
		retval = 0;
		break;
}

print_out("Value: %i\n",retval);

Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46930
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Inlägg av TomasL »

Jo, tänk om livet hade varit så enkelt, Men nu är det Danfoss som har bestämt hur data från deras omvandlare ser ut, tyvärr.:(
En del data är en textsträng, en del int en del double en del word osv.
Dessutom till råga på allt så har jag olika skalfaktorer som varierar beroende på vad jag hämtar från frekvensomvandlaren, så jag måste, vad jag tror hantera varje enskilld data för sig.

Vilket innebär att jag har en switch i första nivån med 9 case (1-9), precis som i din kod, sedan har jag ytterligare en switch i nästa nivå med samma antal case som datapunkter i omformaren. (det finns ingen som helst logik i detta med skalfaktorer och format) Jag har 10 olika format att ta hänsyn till, samt 9 olika skalfaktorer. (allt i en salig blandning).


edit, förtydliganden, och kod:

Kod: Markera allt

switch (index)
  {
  	case INDEX_VLT5K:
  	/*deal with VLT5K specifics*/
  		switch (var)
  		{
  			case vlt_pref_Sts:	/* 001 */
  			/*code*/
  			
  				break;
  			case vlt_pref_Ref:	/* 002 */
  			/*code*/
  			
  				break;
  			case vlt_curr_Sts:	/* 003 */
  			/*code*/
  			
  				break;
....................................... osv
Användarvisningsbild
oJsan
EF Sponsor
Inlägg: 1541
Blev medlem: 11 november 2005, 21:36:51
Ort: Umeå
Kontakt:

Inlägg av oJsan »

Switchar i flera nivåer är nog ändå det enklaste du kan göra i detta fall. Du måste ju inte ha lika många switchar som det är datapunkter!
Något i den här stilen då (vet ju inte så mycket om dina parametrar):

Kod: Markera allt

typedef struct
{
	word	data_type_used; //Indikerar vilken datatyp som använts.
	double	out_double;
	word	out_word;
	char*	out_char_str[20];
} out_values_t;

out_values_t out_value;

//Inläsning
switch(datapunkt)
{
	//Format 1, t.ex. double
	case DP1:
	case DP3:
	case DP4:
		//Metod för att läsa en double från utrustningen
		get_param_double(&out_value, datapunkt);
		out_value.data_type_used = ENUM_DOUBLE;
 		break;

	//Format 2, t.ex. sträng
	case DP2:
	case DP5:
	case DP6:
		//Metod för att läsa en sträng från utrustningen
		get_param_str(&out_value, datapunkt);
		out_value.data_type_used = ENUM_STRING;
 		break;
}

//Skalfaktor eller konvertering
switch(datapunkt)
{
	//De som behöver en viss skalfaktor
	case DP1:
	case DP2:
	case DP3:
		switch(out_value.data_type_used)
		{
			case ENUM_DOUBLE:
				out_value.out_double = out_value.out_double * 100;
				break;
			case ENUM_STRING:
				//Not valid
				break;
		}
 		break;

	//De som behöver en annan skalfaktor
	case DP2:
	case DP5:
	case DP6:
		switch(out_value.data_type_used)
		{
			case ENUM_DOUBLE:
				out_value.out_double = out_value.out_double * 20;
				break;
			case ENUM_STRING:
				//Not valid
				break;
		}
 		break;

}
Har du skrivit en hel webserver så borde ju detta vara rätt trivialt tycker jag... :) eller är det något som vi inte vet om som gör det omöjligt?

Edit: Efter min kod får du väl konvertera structens värden till något enhetligt eller returnera hela structen och göra det "högre upp" i programmet.
Senast redigerad av oJsan 31 maj 2007, 09:42:33, redigerad totalt 1 gång.
Skriv svar