Created
February 9, 2022 22:58
-
-
Save vinthewrench/4d2046c3d3cc0bae7e2fa54bdfb89dac to your computer and use it in GitHub Desktop.
Using gattlib to read values from victron smart shunt bluetooth
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
clang++ -Wall -o testshunt testshunt.c /usr/lib/libgattlib.so | |
*/ | |
#include <assert.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdbool.h> | |
#include "gattlib.h" | |
volatile bool g_operation_completed; | |
/* | |
As Documented at | |
https://community.victronenergy.com/questions/93919/victron-bluetooth-ble-protocol-publication.html | |
*/ | |
const char* uuid_str_SOC = "65970fff-4bda-4c1e-af4b-551c4cf74769"; | |
const char* uuid_str_V = "6597ed8d-4bda-4c1e-af4b-551c4cf74769"; | |
const char* uuid_str_A = "6597ed8c-4bda-4c1e-af4b-551c4cf74769"; | |
const char* uuid_str_P = "6597ed8e-4bda-4c1e-af4b-551c4cf74769"; | |
const char* uuid_str_Consumed = "6597eeff-4bda-4c1e-af4b-551c4cf74769"; | |
const char* uuid_str_tempK = "6597edec-4bda-4c1e-af4b-551c4cf74769"; | |
const char* uuid_str_t2go = "65970ffe-4bda-4c1e-af4b-551c4cf74769"; | |
#define MINS_PER_HOUR ((int16_t)(60 )) | |
#define MINS_PER_DAY ((int16_t)(MINS_PER_HOUR * 24 )) | |
static void breakDuration(int16_t minutesIn, | |
int16_t *days, int16_t *hours, int16_t *mins ){ | |
uint16_t remainingMinutes = minutesIn; | |
*days = (remainingMinutes/ MINS_PER_DAY); | |
remainingMinutes = minutesIn - (*days * MINS_PER_DAY); | |
*hours = (remainingMinutes / MINS_PER_HOUR) ; | |
remainingMinutes = minutesIn - ( (*days * MINS_PER_DAY) + (*hours * MINS_PER_HOUR)); | |
*mins = remainingMinutes; | |
} | |
static void connect_cb(gatt_connection_t* connection, void* user_data) { | |
if (connection != NULL) { | |
uuid_t uuid; | |
int err = GATTLIB_SUCCESS; | |
printf("Connected \n"); | |
// get SOC | |
if ( gattlib_string_to_uuid(uuid_str_SOC, strlen(uuid_str_SOC) + 1, &uuid) == 0){ | |
size_t len; | |
uint8_t *buffer = NULL; | |
err = gattlib_read_char_by_uuid(connection, &uuid, (void **)&buffer, &len); | |
if(err == GATTLIB_SUCCESS){ | |
int16_t i = (buffer[1] << 8) | buffer[0]; | |
double val = (double) (i) / 100.0; | |
printf("\t%-10s: %0.2f%%\n", "SOC", val); | |
free(buffer); | |
} | |
} | |
// Get Battery Voltage | |
if ( gattlib_string_to_uuid(uuid_str_V, strlen(uuid_str_V) + 1, &uuid) == 0){ | |
size_t len; | |
uint8_t *buffer = NULL; | |
err = gattlib_read_char_by_uuid(connection, &uuid, (void **)&buffer, &len); | |
if(err == GATTLIB_SUCCESS){ | |
int16_t i = (buffer[1] << 8) | buffer[0]; | |
double val = (double) (i) / 100.0; | |
printf("\t%-10s: %0.2fV\n", "Voltage", val); | |
free(buffer); | |
} | |
} | |
// Get Battery Current | |
if ( gattlib_string_to_uuid(uuid_str_A, strlen(uuid_str_A) + 1, &uuid) == 0){ | |
size_t len; | |
uint8_t *buffer = NULL; | |
err = gattlib_read_char_by_uuid(connection, &uuid, (void **)&buffer, &len); | |
if(err == GATTLIB_SUCCESS){ | |
uint16_t i = (buffer[1] << 8) | buffer[0]; | |
double val = (double) (i) / 1000.0; | |
printf("\t%-10s: %0.2fA\n", "Current", val); | |
free(buffer); | |
} | |
} | |
// Get Battery Power | |
if ( gattlib_string_to_uuid(uuid_str_P, strlen(uuid_str_P) + 1, &uuid) == 0){ | |
size_t len; | |
uint8_t *buffer = NULL; | |
err = gattlib_read_char_by_uuid(connection, &uuid, (void **)&buffer, &len); | |
if(err == GATTLIB_SUCCESS){ | |
int16_t i = (buffer[1] << 8) | buffer[0]; | |
double val = (double) (i); | |
printf("\t%-10s: %0.2fW\n", "Power", val); | |
free(buffer); | |
} | |
} | |
// Consumed Ah | |
if ( gattlib_string_to_uuid(uuid_str_Consumed, strlen(uuid_str_Consumed) + 1, &uuid) == 0){ | |
size_t len; | |
uint8_t *buffer = NULL; | |
err = gattlib_read_char_by_uuid(connection, &uuid, (void **)&buffer, &len); | |
if(err == GATTLIB_SUCCESS){ | |
int16_t i = (buffer[1] << 8) | buffer[0]; | |
double val = (double) (i) / 10.0; | |
printf("\t%-10s: %0.2fAh\n", "Consumed", val); | |
free(buffer); | |
} | |
} | |
// Time remaining | |
if ( gattlib_string_to_uuid(uuid_str_t2go, strlen(uuid_str_t2go) + 1, &uuid) == 0){ | |
size_t len; | |
uint8_t *buffer = NULL; | |
err = gattlib_read_char_by_uuid(connection, &uuid, (void **)&buffer, &len); | |
if(err == GATTLIB_SUCCESS){ | |
int16_t i = (buffer[1] << 8) | buffer[0]; | |
if(i == -1) | |
printf("\t%-10s: %s\n", "Time 2 Go", "Infinite"); | |
else | |
{ | |
int16_t days, hours, mins; | |
breakDuration(i, &days, &hours, &mins); | |
//printf("%02x %02x " , buffer[0],buffer[1]); | |
printf("\t%-10s: ","Time 2 Go"); | |
if(days > 0) printf("%d Days ",days); | |
if(hours > 0) printf("%d Hours ", hours); | |
printf("%d Mins ", mins); | |
printf("\n"); | |
} | |
free(buffer); | |
} | |
} | |
// Temperaure in Kelvin Ah | |
if ( gattlib_string_to_uuid(uuid_str_tempK, strlen(uuid_str_tempK) + 1, &uuid) == 0){ | |
size_t len; | |
uint8_t *buffer = NULL; | |
err = gattlib_read_char_by_uuid(connection, &uuid, (void **)&buffer, &len); | |
if(err == GATTLIB_SUCCESS){ | |
int16_t i = (buffer[1] << 8) | buffer[0]; | |
double val = (double) (i) / 100.0; | |
val = (val - 273.15)* 1.8000 + 32.00; | |
printf("\t%-10s: %0.2f°F\n", "Bat Temp", val); | |
free(buffer); | |
} | |
} | |
} | |
g_operation_completed = true; | |
} | |
int main(int argc, char *arg[]) { | |
gatt_connection_t* con; | |
const char* deviceID = "CA:9C:B9:8D:E3:70"; | |
g_operation_completed = false; | |
con = gattlib_connect_async(NULL, deviceID, BDADDR_LE_RANDOM, connect_cb, 0); | |
if (con == NULL) { | |
fprintf(stderr, "Fail to connect to the bluetooth device %s.\n",deviceID); | |
return 1; | |
} else { | |
while (!g_operation_completed); | |
gattlib_disconnect(con); | |
printf("Disconnected \n"); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment