Projekt MQTT-Demo

Aus Verteilte Systeme - Wiki
Wechseln zu: Navigation, Suche

Introduction

In the MQTT Demo, we want to display different sensor data, from different sensor notes, at some different andriod based devices. These devices are smartphones, tablets or something else on which runs andriod. For transmitting the data of the differnend sensor we want to use the MQTT-protocol. Therefore the sensor notes must connect to a MQTT-Broker and publish their different values of sensor data under topics and the endpoits subscribe thees topics. So we have the following infrastructure:MQTT demo.png

An own implemented MQTT-client subscribe the data on the andriod based devices. In the demo we use a Rasyberry PI, which is connected witch a Pi UPS(uninterruptable power supply) board from CW2.

Publisher on the Rasyberry PI

The Publisher in the MQTT-Demo is a little C-program called ups_mqtt, which uses the mosquitto library to publish the batterie status of the PI UPS, the topic of this status is "ups_batterie_status". To get value of the status from the PI UPS, the program comunictate over I²C with the board.

Usage

The following options can set for the program:

option name description must be set
-b "ip address or name of the broker" set the ip address or the name of the MQTT broker yes
-p "mqtt port" set the port to which the MQTT broker use yes
-u "mqtt user" set the user for the MQTT broker no
-h show usage informations no

So the default call is: sudo ups_mqtt -b "ip address or name of the broker" -p "MQTT port".

Comunication with the UPS

To communicate with the UPS over I²C the program use the included I²C library of the Wiring PI library (see). The used protocol to request the status of the batterie is very simple:

The I²C address of the board is 0x18.

To request the status the program send the byte 0x00 to the board and the board, then it receives one byte which the board replies. The informations about the status of the batterie is include in the first three bits of the byte, so the byte is structured as the following table shows:

bit 0 1 2 3 - 7
value 1 if power supply over Vcc 1 if power supply over the batterie 1 if the batterie power is low reserved

The this function reads the battrie status of the PI UPS:

int get_battrie_status(int fd_i2c)
{
    // read the battrie status
    int retval = 0;
    retval = wiringPiI2CWrite(fd_i2c, GET_STATUS); // ask for the status
    if(retval == -1)
    	return ERROR_GET_STAT;
    retval = wiringPiI2CRead(fd_i2c); // read the status
    if(retval == -1)
    	return ERROR_R_STAT;
    return retval;
}

Publishing the data

To publishing data over MQTT with the mosquitto library, the program first need to initialize the library and create a new instance of a mosquitto client. After this the program have to register callback functions for connection and disconnection events. With these callbacks the program is able to recognize if a connection buildup was successful or if a connection was demolished. The program also register a callback function for publishing event to check the id of the published message by this the program recognize if messages were lost.

The impmentation of the are like:

void connect_callback(struct mosquitto *mosq, void *obj, int result)
{
	client_state_t* state = (client_state_t*)  obj; 
	// check if we are connectet or we get errors
	switch(result)
	{
		case CON_SUCCESS:
			state->connected = true;
			break;
		case CON_REFUSED_PROTOCOL_VER:
		case CON_REFUSED_ID_REJECTED:
		case CON_REFUSED_BROKER_UNA:
			printf("Error Connect\n");
			state->connected = false;
			break;
			
	}
}
void disconnect_callback(struct mosquitto *mosq, void *obj, int result)
{
	
	client_state_t* state = (client_state_t*)  obj; 
	// check the reason for the disconnect
	if(result != DISCON_CLIENT)
		printf("Unexpected disconnection");
	state->connected = false;
}
void publish_callback(struct mosquitto *mosq, void *obj, int mid)
{
	client_state_t* state = (client_state_t*)  obj; 
	// check if message id is the same as the last one (lost message)
	if(state->last_mid == mid)
	{
		mosquitto_disconnect(mosq);
		state->dis_wrong_mes_id = true;
	}	
	else
		state->last_mid = mid;
}

The mosqitto library allows to set an address on whitch points the obj parameter in the callbacks. By this the state of the MQTT-client can be manipulate. Therfor the structure client_state_t was defined as follow:

// struct whitch contains the informations for the mosqitto callbacks
typedef struct
{
	bool connected;          // are we connented?
	bool dis_wrong_mes_id;   // are we disconncendt cause of a wrong message id while publishing  
	int mid;		 // currend message id
	int last_mid;	         // last message id
} client_state_t;

After the callback registrations the program is able to connect to a MQTT broker and publish messages under a topic.

MQTT client