Add MQTT client libs, extract meter data to main function
This commit is contained in:
parent
7b21d0753e
commit
2db71059f6
2
Makefile
2
Makefile
@ -1,4 +1,4 @@
|
|||||||
# Makefile
|
# Makefile
|
||||||
|
|
||||||
main:
|
main:
|
||||||
gcc everblu_meters.c -o everblu_meters -lwiringPi -lpthread -Wall
|
gcc everblu_meters.c -o everblu_meters -lwiringPi -lmosquitto -lpthread -Wall
|
||||||
|
@ -24,7 +24,7 @@ The project runs on Raspberry Pi with an RF transreciver (CC1101).
|
|||||||
## Configuration
|
## Configuration
|
||||||
1. Enable SPI in raspi-config.
|
1. Enable SPI in raspi-config.
|
||||||
2. Install WiringPi from https://github.com/WiringPi/WiringPi/
|
2. Install WiringPi from https://github.com/WiringPi/WiringPi/
|
||||||
3. Install mosquitto-dev: `apt install mosquitto-dev`
|
3. Install libmosquitto-dev: `apt install libmosquitto-dev`
|
||||||
4. Set meter serial number and production date in `cc1101.c`, it can be found on the meter label itself:
|
4. Set meter serial number and production date in `cc1101.c`, it can be found on the meter label itself:
|
||||||

|

|
||||||
5. Compile the code with `make`
|
5. Compile the code with `make`
|
||||||
|
56
cc1101.c
56
cc1101.c
@ -14,8 +14,15 @@ uint8_t CC1101_status_FIFO_FreeByte=0;
|
|||||||
uint8_t CC1101_status_FIFO_ReadByte=0;
|
uint8_t CC1101_status_FIFO_ReadByte=0;
|
||||||
uint8_t debug_out=0;
|
uint8_t debug_out=0;
|
||||||
|
|
||||||
#define METER_YEAR 20
|
struct tmeter_data {
|
||||||
#define METER_SERIAL 1234567
|
int liters;
|
||||||
|
int reads_counter; // how many times the meter has been readed
|
||||||
|
int battery_left; //in months
|
||||||
|
int time_start; // like 8am
|
||||||
|
int time_end; // like 4pm
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define TX_LOOP_OUT 300
|
#define TX_LOOP_OUT 300
|
||||||
@ -421,19 +428,28 @@ uint8_t cc1101_wait_for_packet(int milliseconds)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_meter_report (uint8_t *decoded_buffer , uint8_t size)
|
struct tmeter_data parse_meter_report (uint8_t *decoded_buffer , uint8_t size)
|
||||||
{
|
{
|
||||||
if (size >= 30)
|
struct tmeter_data data;
|
||||||
{
|
|
||||||
echo_debug(1,"\r\n%u/%u/20%u %u:%u:%u ",decoded_buffer[24],decoded_buffer[25],decoded_buffer[26],decoded_buffer[28],decoded_buffer[29],decoded_buffer[30]);
|
|
||||||
echo_debug(1,"%u litres ",decoded_buffer[18]+decoded_buffer[19]*256 + decoded_buffer[20]*65536 + decoded_buffer[21]*16777216);
|
if (size >= 30)
|
||||||
}
|
{
|
||||||
if (size >= 48)
|
//echo_debug(1,"\r\n%u/%u/20%u %u:%u:%u ",decoded_buffer[24],decoded_buffer[25],decoded_buffer[26],decoded_buffer[28],decoded_buffer[29],decoded_buffer[30]);
|
||||||
{
|
//echo_debug(1,"%u litres ",decoded_buffer[18]+decoded_buffer[19]*256 + decoded_buffer[20]*65536 + decoded_buffer[21]*16777216);
|
||||||
echo_debug(1,"Num %u %u Mois %uh-%uh ",decoded_buffer[48], decoded_buffer[31],decoded_buffer[44],decoded_buffer[45]);
|
|
||||||
decoded_buffer[43]=0; //to be sure that string will end
|
data.liters = decoded_buffer[18]+decoded_buffer[19]*256 + decoded_buffer[20]*65536 + decoded_buffer[21]*16777216;
|
||||||
echo_debug(1,"serial:%s ",&decoded_buffer[32]);
|
}
|
||||||
}
|
if (size >= 48)
|
||||||
|
{
|
||||||
|
//echo_debug(1,"Num %u %u Mois %uh-%uh ",decoded_buffer[48], decoded_buffer[31],decoded_buffer[44],decoded_buffer[45]);
|
||||||
|
data.reads_counter = decoded_buffer[48];
|
||||||
|
data.battery_left = decoded_buffer[31];
|
||||||
|
data.time_start = decoded_buffer[44];
|
||||||
|
data.time_end = decoded_buffer[45];
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the start- and stop-bits in the bitstream , also decode oversampled bit 0xF0 => 1,0
|
// Remove the start- and stop-bits in the bitstream , also decode oversampled bit 0xF0 => 1,0
|
||||||
@ -565,6 +581,7 @@ int receive_radian_frame(int size_byte,int rx_tmo_ms ,uint8_t*rxBuffer,int rxBuf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(l_tmo<rx_tmo_ms) echo_debug(debug_out,"frame received\r\n"); else return 0;
|
if(l_tmo<rx_tmo_ms) echo_debug(debug_out,"frame received\r\n"); else return 0;
|
||||||
|
|
||||||
/*stop reception*/
|
/*stop reception*/
|
||||||
CC1101_CMD(SFRX);
|
CC1101_CMD(SFRX);
|
||||||
CC1101_CMD(SIDLE);
|
CC1101_CMD(SIDLE);
|
||||||
@ -597,8 +614,9 @@ int receive_radian_frame(int size_byte,int rx_tmo_ms ,uint8_t*rxBuffer,int rxBuf
|
|||||||
|
|
||||||
l'outils de reléve doit normalement acquité
|
l'outils de reléve doit normalement acquité
|
||||||
*/
|
*/
|
||||||
uint8_t scenario_releve(void)
|
struct tmeter_data get_meter_data(void)
|
||||||
{
|
{
|
||||||
|
struct tmeter_data sdata;
|
||||||
uint8_t marcstate = 0xFF;
|
uint8_t marcstate = 0xFF;
|
||||||
uint8_t wupbuffer[] ={0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55};
|
uint8_t wupbuffer[] ={0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55};
|
||||||
uint8_t wup2send =77;
|
uint8_t wup2send =77;
|
||||||
@ -658,14 +676,16 @@ uint8_t scenario_releve(void)
|
|||||||
rxBuffer_size = receive_radian_frame(0x7C,700,rxBuffer,sizeof(rxBuffer));
|
rxBuffer_size = receive_radian_frame(0x7C,700,rxBuffer,sizeof(rxBuffer));
|
||||||
if (rxBuffer_size)
|
if (rxBuffer_size)
|
||||||
{
|
{
|
||||||
if (debug_out)show_in_hex_array(rxBuffer, rxBuffer_size);
|
if (debug_out) show_in_hex_array(rxBuffer, rxBuffer_size);
|
||||||
|
|
||||||
meter_data_size=decode_4bitpbit_serial(rxBuffer, rxBuffer_size,meter_data);
|
meter_data_size=decode_4bitpbit_serial(rxBuffer, rxBuffer_size,meter_data);
|
||||||
// show_in_hex(meter_data,meter_data_size);
|
// show_in_hex(meter_data,meter_data_size);
|
||||||
display_meter_report(meter_data,meter_data_size);
|
sdata = parse_meter_report(meter_data,meter_data_size);
|
||||||
|
return sdata;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
echo_debug(debug_out,"TMO on REC\r\n");
|
echo_debug(debug_out,"TMO on REC\r\n");
|
||||||
}
|
}
|
||||||
return meter_data_size;
|
return;
|
||||||
}
|
}
|
||||||
|
107
everblu_meters.c
107
everblu_meters.c
@ -1,24 +1,117 @@
|
|||||||
/* the radian_trx SW shall not be distributed nor used for commercial product*/
|
/* the radian_trx SW shall not be distributed nor used for commercial product*/
|
||||||
/* it is exposed just to demonstrate CC1101 capability to reader water meter indexes */
|
/* it is exposed just to demonstrate CC1101 capability to reader water meter indexes */
|
||||||
/* there is no Warranty on radian_trx SW */
|
|
||||||
|
#define METER_YEAR 16
|
||||||
|
#define METER_SERIAL 123456
|
||||||
|
|
||||||
|
#define MQTT_HOST "localhost"
|
||||||
|
#define MQTT_PORT 1883
|
||||||
|
#define MQTT_KEEP_ALIVE 60
|
||||||
|
#define MQTT_MSG_MAX_SIZE 512
|
||||||
|
#define MQTT_TOPIC_NUM 3
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <mosquitto.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "everblu_meters.h"
|
#include "everblu_meters.h"
|
||||||
|
#include "cc1101.c"
|
||||||
|
|
||||||
|
void my_message_callback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(message->payloadlen){
|
||||||
|
printf("%s %s", message->topic, (char *)message->payload);
|
||||||
|
}else{
|
||||||
|
printf("%s (null)\n", message->topic);
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void my_connect_callback(struct mosquitto *mosq, void *userdata, int result)
|
||||||
|
{
|
||||||
|
if(!result){
|
||||||
|
/* Subscribe to broker information topics on successful connect. */
|
||||||
|
mosquitto_subscribe(mosq, NULL, "CCYY ", 2);
|
||||||
|
}else{
|
||||||
|
fprintf(stderr, "Connect failed\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void my_subscribe_callback(struct mosquitto *mosq, void *userdata, int mid, int qos_count, const int *granted_qos)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
printf("Subscribed (mid: %d): %d", mid, granted_qos[0]);
|
||||||
|
for(i=1; i<qos_count; i++){
|
||||||
|
printf(", %d", granted_qos[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void my_log_callback(struct mosquitto *mosq, void *userdata, int level, const char *str)
|
||||||
|
{
|
||||||
|
/* Pring all log messages regardless of level. */
|
||||||
|
printf("%s\n", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void IO_init(void)
|
void IO_init(void)
|
||||||
{
|
{
|
||||||
wiringPiSetup () ;
|
wiringPiSetup();
|
||||||
pinMode (GDO2, INPUT);
|
pinMode (GDO2, INPUT);
|
||||||
pinMode (GDO0, INPUT);
|
pinMode (GDO0, INPUT);
|
||||||
|
|
||||||
cc1101_init();
|
cc1101_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
fflush(stdout);
|
struct tmeter_data meter_data;
|
||||||
|
struct mosquitto *mosq = NULL;
|
||||||
|
char buff[MQTT_MSG_MAX_SIZE];
|
||||||
|
|
||||||
|
mosquitto_lib_init();
|
||||||
|
mosq = mosquitto_new(NULL, true, NULL);
|
||||||
|
if(!mosq){
|
||||||
|
printf("ERROR: Create MQTT client failed..\n");
|
||||||
|
mosquitto_lib_cleanup();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set callback functions
|
||||||
|
mosquitto_log_callback_set(mosq, my_log_callback);
|
||||||
|
mosquitto_connect_callback_set(mosq, my_connect_callback);
|
||||||
|
mosquitto_message_callback_set(mosq, my_message_callback);
|
||||||
|
mosquitto_subscribe_callback_set(mosq, my_subscribe_callback);
|
||||||
|
|
||||||
|
|
||||||
|
//Connect to MQTT server
|
||||||
|
if(mosquitto_connect(mosq, MQTT_HOST, MQTT_PORT, MQTT_KEEP_ALIVE)){
|
||||||
|
fprintf(stderr, "ERROR: Unable to connect to MQTT broker.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
//Start a thread, and call mosquitto? Loop() continuously in the thread to process network information
|
||||||
|
int loop = mosquitto_loop_start(mosq);
|
||||||
|
if(loop != MOSQ_ERR_SUCCESS)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: failed to create mosquitto loop");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//mosquitto_publish(mosq,NULL,"CCYY ",strlen(buff)+1,buff,0,0);
|
||||||
|
|
||||||
IO_init();
|
IO_init();
|
||||||
scenario_releve();
|
meter_data = get_meter_data();
|
||||||
|
|
||||||
|
printf("Liters: %i\n", meter_data.liters);
|
||||||
|
|
||||||
|
mosquitto_destroy(mosq);
|
||||||
|
mosquitto_lib_cleanup();
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -59,4 +59,6 @@ typedef unsigned char T_BOOL; //1 octets
|
|||||||
#include "utils.c"
|
#include "utils.c"
|
||||||
#include "wiringPi.h"
|
#include "wiringPi.h"
|
||||||
#include "wiringPiSPI.h"
|
#include "wiringPiSPI.h"
|
||||||
#include "cc1101.c"
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user