No idea if this would be helpful to others but I crated a simple Bluetooth Scanner that will look for a specific MAC address, extract the advertisement data, and post that to MQTT. My purpose was to scan for Victron MPPT Bluetooth advertisements with my Shelly Uni Plus and post that data to MQTT [so I could have another small service decrypt that data for me]. Anyway, configuration is at the top:
- Bluetooth MAC address.
- Flag to turn on and off device data printing (for debugging)
- MQTT topic to post the found data to.
I keep hoping Shelly will make their new AES-CRT routines available for the Shelly Uni Plus but it looks like they are limiting that to Gen3/Gen4 devices so I can't do my decoding here!
Code
// ------- Configuration!-----------------\
const mac = "df:3a:0a:93:84:73";
const printResults = false;
const mqttTopic = Shelly.getComponentConfig("Mqtt").topic_prefix + "/Solar/raw"
// ---------------------------------------\
// Log Topic to be used
print("MQTT Topic: ", mqttTopic);
// Function to turn binary data to hex
function toHex(data) {
if (!data) return '';
let hex = '';
for (let i = 0; i < data.length; i++) {
let h = data.charCodeAt(i).toString(16);
hex += h.length === 1 ? '0' + h : h;
}
return hex.toUpperCase();
}
// Function to handle Bluetooth Scan Events
function handleScanEvent(event, result, userdata) {
switch(event) {
case BLE.Scanner.SCAN_START:
print("Scan started");
break;
case BLE.Scanner.SCAN_STOP:
print("Scan stopped");
break;
case BLE.Scanner.SCAN_RESULT:
// Filter Mac Address
if (result.addr != mac) break;
// Publish Results to MQTT
if (result.advData && MQTT.isConnected())
MQTT.publish(mqttTopic, toHex(result.advData));
// Print Results?
if (!printResults) break;
// Print Basic Device Info
print("Device found:");
print(" - Address:", result.addr);
print(" - RSSI:", result.rssi);
// Print Local Name
if (result.local_name) {
print(" - Name:", result.local_name);
}
// Print Manufacterer Data
if (result.manufacturer_data) {
print(" - Manufacturer data (HEX):", toHex(result.manufacturer_data));
}
// Print Advertisement Data
if (result.advData) {
print(" - Advertisement data (HEX-Encrypted):", toHex(result.advData));
}
// Afficher les services si disponibles
if (result.service_uuids) {
try {
print(" - Services:", JSON.stringify(result.service_uuids));
} catch (e) {
print(" - Services: [Format error]");
}
}
print("------------------------");
break;
}
}
// Scan Options
let scanOptions = {
duration_ms: BLE.Scanner.INFINITE_SCAN, // Scan FOREVER!
active: true, // Scan actif pour obtenir plus d'informations
interval_ms: 100, // Intervalle entre les scans
window_ms: 30 // Fenêtre de scan
};
// Subscribe to Bluetooth Events
BLE.Scanner.Subscribe(handleScanEvent);
// Start Scanning
let result = BLE.Scanner.Start(scanOptions);
if (result) {
print("Scan started successfully");
} else {
print("Failed to start scan");
}
Alles anzeigen