Kundens struktur

Webklienten giver en brugergrænseflade til en ekstern Web-IO. Kommunikationen mellem Web-IO og webklienten foregår via IoT-protokollen MQTT.

Klienten består af de tre filer:

  1. webio.html
  2. ui.js
  3. mqtt.js

HTML-filen indeholder markup til den grafiske repræsentation. Javascript-filen mqtt.js indeholder de MQTT-specifikke funktioner såsom forbindelsesstyring, Publish og Subscribe. Filen ui.js er grænsefladen mellem MQTT-klienten og webgrænsefladen. Den indeholder de funktioner, der opdaterer grænsefladen, når der modtages et abonnement, og udløser afsendelsen af en PUBLISH-pakke, når der er en brugerinteraktion.


Kommunikation mellem webklient og web-IO

Den tilstødende repræsentation af kommunikationen mellem Web-IO og Web Client brokeren er ikke vist for enkelthedens skyld.

Kommunikationen foregår via emnerne mywebio//status, hvormed Web-IO’en offentliggør den aktuelle skiftestatus, og mywebio//set, hvormed webgrænsefladen sender en skiftanmodning til Web-IO’en.

  1. Når webklienten har oprettet forbindelse, modtager den tilstandene for de enkelte ind- og udgange som bevarede meddelelser og repræsenterer dem i en HTML-tabel.
  2. Så snart brugeren klikker på et output (her Output 0), udsender webklienten en Publish med payloaden “ON” og emnet “mywebio/output0/set”. Den ubekræftede anmodning vises i webklienten med en blegere farve.
  3. Web-IO’en reagerer på modtagelsen af abonnementet ved at tænde for det tilsvarende output. Derefter sender den en Publish med den nye tilstand som payload og emnet “mywebio/output0/status”. Så snart webklienten har modtaget beskeden, viser den outputtet i fuld farveintensitet.

Bemærk: Hvis der er flere på hinanden følgende ændringsanmodninger uden en bekræftelse fra Web-IO’en, bliver det tilsvarende output nedtonet og aktiveres ikke igen, før Web-IO’en har offentliggjort sin aktuelle status.


Forberedelse: Konfiguration af brokeren og Web-IO’en

Angiv brugere og adgangsrettigheder

I denne vejledning, som i vejledningen Box-2-Box via MQTT, bruges den gratis broker cloudmqtt.com til små applikationer.

For nemheds skyld vil der kun blive oprettet en enkelt bruger med brede rettigheder:

Brugernavnwebio

Skriv autorisationAutorisation til læsning
##

Grundlæggende indstillinger for MQTT

Web-IO er konfigureret til udveksling med brokeren på siden “Communication paths >> MQTT”.

  1. Aktivér først MQTT.
  2. Indtast brugernavn og adgangskode.
  3. Indtast forbindelsesoplysningerne for brokeren.

Opret handlinger til at skifte udgangene.

Åbn nu siden “Handlinger”, og klik på “Tilføj” for at oprette handlingerne til modtagelse af et abonnement.

  1. Aktivér handlingen, og giv den et logisk navn.
  2. Udløseren er modtagelse af et MQTT-abonnement med emnestien mywebio/output0/set og emnet textON.
  3. Når triggeren indtræffer, skal Web-IO skifte en udgang, i dette tilfælde udgang 0 til “ON”.

Gentag det sidste trin, indtil du har defineret i alt fire handlinger: Output 0 til ON, Output 0 til OFF, Output 1 til ON og Output 1 til OFF.

Opret handlinger til udgivelse af IO-tilstande

I det sidste konfigurationstrin oprettes handlingerne med en MQTT-udgivelse, når der sker en statusændring på et in- eller output.

  1. Sæt handlingen til aktiv, og giv den et logisk navn.
  2. Vælg som triggerindgang, og vælg derefter en ændring til OFF for Input0.
  3. Som handling skal en MQTT-udgivelse udføres.
  4. Emnet for udgivelse af en ny status er “mywebio/input0/status”.
  5. Payload (Topic Text) for en ændring til OFF er “OFF”.
  6. Topic Clear Text er den besked, der sendes, når udløseren ikke længere er til stede, dvs. “ON”.

Gentag opsætningen af handlingen for den anden indgang og for begge udgange.


Implementering af webklienten

I det følgende gennemgås de tre filer webio.html, mqtt.js og ui.js i detaljer. HTML-filen indeholder kun de grundlæggende designelementer, og derfor vil den kun blive gennemgået kort. Her følger en mere detaljeret gennemgang af de to JavaScript-filer.

Download alle filer

webio.html: Den grafiske repræsentation

		My Web-IO
			body {font-family: sans-serif;}
			table {empty-cells: show;}
			.on {background-color: #00FF00;}
			.off {background-color: #FF0000;}
			.set_on {background-color: #CCFFCC;}
			.set_off {background-color: #FFCCCC;}
			.unknown {background-color: #DDDDDD;}
			.on:before, .set_on:before {content: "ON";}
			.off:before, .set_off:before {content: "OFF";}
			.unknown:before	{content: "?";}
			#output0,#output1{cursor: pointer;}
		My Web-IO InputOutput[0]  [1]  
  • Linje 4-6: Indarbejdelse af PAHO-JavaScript-klienten. Alternativ URL: https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js
  • Linje 7 og 8: Inkorporering af de lokale JS-filer. Attributten defer sikrer, at de funktioner, der tilgår HTML-elementer, ikke udføres, før hele siden er blevet indlæst.
  • Linjerne 12-24: Stiloplysninger for de forskellige stater. Ud over at tildele en farve indledes elementet enten med teksten ON, OFF eller ?
  • Linjerne 29-45: Tabellen, der viser ind- og udgange. De enkelte ind- og udgange repræsenteres her af tabelceller, som tildeles en CSS-klasse til visning. Elementerne identificeres med ID’er, der hedder præcis det samme som ind- og udgangene i Web-IO.

mqtt.js: Den faktiske MQTT-klient

Filen mqtt.js indeholder funktionerne til at åbne forbindelsen til MQTT-brokeren og til at modtage og sende beskeder.

/*
	* MQTT-WebClient example for Web-IO 4.0
*/
var hostname = "m21.cloudmqtt.com";
var port = 37719;
var clientId = "webio4mqttexample";
clientId += new Date().getUTCMilliseconds();;
var username = "webclient";
var password = "Super$icher123";
var subscription = "mywebio/+/status";

mqttClient = new Paho.MQTT.Client(hostname, port, clientId);
mqttClient.onMessageArrived = MessageArrived;
mqttClient.onConnectionLost = ConnectionLost;
Connect();

/*Initiates a connection to the MQTT broker*/
function Connect(){
	mqttClient.connect({
	onSuccess: Connected,
	onFailure: ConnectionFailed,
	keepAliveInterval: 10,
	userName: username,
	useSSL: true,
	password: password});
}

/*Callback for successful MQTT connection */
function Connected() {
	console.log("Connected");
	mqttClient.subscribe(subscription);
}

/*Callback for failed connection*/
function ConnectionFailed(res) {
	console.log("Connect failed:" + res.errorMessage);
}

/*Callback for lost connection*/
function ConnectionLost(res) {
	if (res.errorCode !== 0) {
		console.log("Connection lost:" + res.errorMessage);
		Connect();
	}
}

/*Callback for incoming message processing */
function MessageArrived(message) {
	console.log(message.destinationName +" : " + message.payloadString);
	switch(message.payloadString){
		case "ON":
			displayClass = "on";
			break;
		case "OFF":
			displayClass = "off";
			break;
		default:
			displayClass = "unknown";
	}
	var topic = message.destinationName.split("/");
	if (topic.length == 3){
		var ioname = topic[1];
		UpdateElement(ioname, displayClass);
	}
}

Konfigurationsværdier og åbning af en forbindelse

Først indstilles et par konfigurationsværdier:

var hostname 	= "m21.cloudmqtt.com";
var port 		= 37719;
var clientId	= "webio4mqttexample";
clientID += new Date().getUTCMilliseconds();
var username	= "webclient";
var password	= "Super$icher123";
var subscription = "mywebio/+/status";
  • Linje 4 og 5: Forbindelsesoplysningerne til MQTT-mægleren
  • Linje 6: En unik streng, der identificerer den adgangsgivende klient.
  • Linje 7: Instruktionen new Date().getUTCMilliseconds() sikrer, at flere instanser af klienten kan være åbne på samme tid ved at tilføje et aktuelt tidsstempel til klient-ID’et. Flere forbindelser med det samme klient-ID vil blive lukket af brokeren i henhold til standarden.
  • Linje 8 og 9: Brugerens login-data
  • Linje 10: Det emne, hvormed Web-IO’en offentliggør sine tilstande.

Derefter initialiseres klienten:

mqttClient = new Paho.MQTT.Client(hostname, port, clientId);
mqttClient.onMessageArrived = MessageArrived;
mqttClient.onConnectionLost = ConnectionLost;
Connect();
  • Linje 12: Initialisering af MQTT-klienten med mæglerens værtsnavn, porten og det unikke klient-ID.
  • Linje 13: MessageArrived() er callback-funktionen, som aktiveres, når der modtages et abonnement.
  • Linje 14: ConnectionLost() påkaldes, hvis en forbindelse afsluttes.
  • Linje 15: Connect bruges til at åbne forbindelsen.

Funktionen Connect() er ansvarlig for at åbne forbindelsen til MQTT-mægleren. Konfigurationsobjektet indeholder de allerede specificerede parametre samt callback-funktionerne for en vellykket eller mislykket forbindelse.

/*Initiates a connection to the MQTT broker*/
function Connect(){
	mqttclient.connect({
		onSuccess:	Connected,
		onFailure:	ConnectionFailed,
		keepAliveInterval: 10,
		userName:	username,
		useSSL:		true,
		password:	password
	});
}
  • Linje 19: Forbindelsen påkalder metoden connect() i MQTT-klienten.
  • Linje 20: Efter vellykket åbning af en forbindelse udføres callback-funktionen Connected().
  • Linje 21: Efter et mislykket forbindelsesforsøg påkaldes ConnectionFailed().
  • Linje 24: Kommunikationen foregår krypteret via TLS.

Callback-funktionerne

I det første afsnit blev fire callback-funktioner nævnt: MessageArrived() og ConnectionLost() blev indstillet som MQTT-klientattributter, Connected() og ConnectionFailed() blev sendt til funktionen Connect()i konfigurationsobjektet.

Connected() udføres, hvis forbindelsen blev åbnet med succes.

/*Callback for successful MQTT connection */
function Connected() {
	console.log("Connected");
	mqttclient.subscribe(subscription);
}
  • Linje 31: Forbindelsesstatus vises i JavaScript-konsollen.
  • Linje 32: Da det ikke er en vedvarende forbindelse, skal emnet gentilmeldes til beskeder fra Web-IO, hver gang en forbindelse åbnes.

Når åbningen af forbindelsen er mislykkedes, ConnectionFailed() udlæses informationerne på JavaScript-konsollen.

/*Callback for failed connection*/
function ConnectionFailed(res) {
		console.log("Connect failed:" + res.errorMessage);
}

Hvis en forbindelse afbrydes ConnectionLost() påkaldes.

/*Callback for lost connection*/
function ConnectionLost(res) {
	if (res.errorCode !== 0)
	{
	console.log("Connection lost:" + res.errorMessage);
	Connect();
	}
}
  • Linje 43: Oplysninger om den afbrudte forbindelse vises på JavaScript-konsollen.
  • Linje 44: Derefter åbnes en ny forbindelse.

Den bredeste funktion er MessageArrived(). Den øverste del af funktionen analyserer payload-strengen. Den bruges til at bestemme den CSS-klasse, der er tildelt det tilsvarende element.

/*Callback for incoming message processing */
function MessageArrived(message) {
	switch(message.payloadString){
		case "ON":
			displayClass = "on";
			break;
		case "OFF":
			displayClass = "off";
			break;
		default:
			displayClass = "unknown";
	}
  • Linje 50: Meddelelsesobjektet har en attribut payloadString, som indeholder indholdet af den transmitterede meddelelse.
  • Linje 51-56: Når meddelelsens indhold er “ON”, sættes variablen displayClass til “on”. Hvis nyttelasten er “OFF”, sættes den til “off”.
  • Linje 57-58: Når der er en defekt payload, sættes displayklassen til “ukendt”.

Den nederste del af funktionen bestemmer, hvilket in- eller output der skal opdateres:

var topic = message.destinationName.split("/");
	if (topic.length == 3){
		var ioname = topic[1];
		UpdateElement(ioname, displayClass);
	}
}
  • Linje 61: Først opdeles message.destinationName, dvs. emnet for meddelelsen, ved hjælp af strengmetoden split() på tegnet “l” i sine individuelle medlemmer, og disse gemmes i arrayet topic.
  • Linje 63: For mywebio/ioname/status er det midterste element navnet på det tilsvarende in- eller output.
  • Linje 64: DOM-elementet ioname tildeles CSS-klassen UpdateElement() i funktionen displayClass.

ui.js: Forbindelsen mellem HTML-siden og MQTT-klienten

ui.js indeholder de funktioner, der opdaterer repræsentationen af HTML-siden, og som påkalder MQTT-klientfunktionerne efter en brugerinteraktion.

/*
	* Web-IO 4.0: MQTT WebSocket example
	*/

/* Updates the CSS class of an DOM element */
function UpdateElement(ioname, displayClass){
	var cell = document.getElementById(ioname);
	if (cell){
		cell.className = displayClass;
	}
	}

	/* Toggles an input in the web interfaces and
	* initiates an MQTT publish */
function ToggleOutput(ioname){
	var cell = document.getElementById(ioname);
	switch (cell.className){
	case "on":
		var message = new Paho.MQTT.Message("OFF");
		message.destinationName = "webio/" + ioname + "/set";
		mqttClient.send(message);
		cell.className = "set_off";
		break;
	case "off":
		var message = new Paho.MQTT.Message("ON");
		message.destinationName = "webio/" + ioname + "/set";
		mqttClient.send(message);
		cell.className = "set_on";
		break;
	default:
		cell.className = "unknown";
		break;
	}

};

/* Adds an Click-Event-Listener to a table cell, so that after
	* a click the element can is toggeled */
function EnableToggle(ioname){
		var cell = document.getElementById(ioname)
		if (cell){
			cell.addEventListener("click",
				function(){
				ToggleOutput(ioname)
			},
				true);
		}
	}

/*Initialize elements that can be toggled my by click*/
EnableToggle("output0");
EnableToggle("output1");

Opdatering af displayet ved hjælp af MQTT-klienten

Ved hjælp af funktionen UpdateElement() indstiller MQTT-klienten CSS-klassen for den tilsvarende tabelcelle til den aktuelle status, når der modtages et abonnement.

/* Updates the CSS class of an DOM element */
function UpdateElement(ioname, displayClass){
	var cell = document.getElementById(ioname);
	if (cell){
		cell.className = displayClass;
	}
	}
  • Linje 6: Funktionen får DOM-elementets ID og CSS-klassen.
  • Linje 9: Denne klasse er tildelt elementet.

Brugerinteraktioner

Funktionen ToggleOutput() justerer sin repræsentation, når der klikkes på et output, og sender en tilsvarende MQTT-publicering. Hvis den aktuelle klasse er on, tildeles den klassen set_off, hvis klassen er off, tildeles den den nye klasse set_on. I alle andre tilfælde er udgangens aktuelle status ubekræftet, og displayet er tildelt klassen unknown funktion.

/* Toggles an input in the web interfaces and
	* initiates an MQTT publish
	*/
function ToggleOutput(ioname){
	var cell = document.getElementById(ioname);
	switch (cell.className){
	case "on":
		var message = new Paho.MQTT.Message("OFF");
		message.destinationName = "webio/" + ioname + "/set";
		mqttClient.send(message);
		cell.className = "set_off";
		break;
	case "off":
		var message = new Paho.MQTT.Message("ON");
		message.destinationName = "webio/" + ioname + "/set";
		mqttClient.send(message);
		cell.className = "set_on";
		break;
	default:
		cell.className = "unknown";
		break;
	}
};
  • Linje 16: Funktionen får ID’et på det DOM-element, der repræsenterer outputtet.
  • Linje 18: Afhængigt af elementets aktuelle klasse er
  • Linje 19-24, 25-30 og 21-33: Den nye klasse sættes til set_on, set_off eller unknown.

For at funktionen ToggleOutput() kan påkaldes, når der klikkes på en tabelcelle, tilføjer EnableToggle() en eventhandler for et museklik til de transmitterede elementer.

/* Adds an Click-Event-Listener to a table cell, so that after
	* a click the element can is toggeled
	*/
function EnableToggle(ioname){
		var cell = document.getElementById(ioname)
		if (cell){
			cell.addEventListener("click",
				function(){
				ToggleOutput(ioname)
			},
				true);
		}
	}
  • Linje 40: Metoden får navnet på en IO.
  • Linje 41: Dette navn bruges til at henvise til den tilsvarende tabelcelle.
  • Linje 43-47: Ved hjælp af metoden addEventListener() tildeles elementet cell en eventhandler for en click. Når der klikkes på det tilsvarende element, skal funktionen ToggleOutput() aktiveres med navnet på IO som parameter.

Til sidst påkaldes EnableToggle() for begge elementer "output1" og "output2":

/*Initialize elements that can be toggled my by click*/
EnableToggle("output0");
EnableToggle("output1");

Gennemgå denne tutorial med hardware

Vil du gerne arbejde dig igennem denne tutorial, men har du ikke den nødvendige hardware? Vi vil med glæde give dig en Web-IO Digital 4.0 som prøve.

Kom i gang - bestil en prøveversion i 30 dage.

Prøv vores produkter fra Wiesemann & Theis gratis i 30 dage ved at skrive det i ordrebekræftelsen: Ønsker at teste produktet.
Hvis du ikke ønsker at gøre brug af din returret inden for 30 dage, skal du blot betale den medfølgende faktura. Gratis forsendelse i Danmark.

Bestil prøveversion her:

Wiesemann & Theis GmbH blev grundlagt i 1979 af Reinhard Wiesemann og Rüdiger Theis. Med 50 ansatte producerer virksomheden mikrocomputer- og netværksteknologi i Wuppertal. I 2001 introducerede Wiesemann & Theis den første industrielle temperatursensor med et netværksinterface, Web-Thermometer, og har næsten 20 års erfaring inden for områderne Industri 4.0 og Internet of Things.

Active Communication har været distributør for W&T siden 1992 i Danmark og siden 2002 også i Sverige, Norge og Island. W&T’s produkter er ekstremt brugervenlige og pålidelige til en konkurrencedygtig pris.