[HOW TO] Advanced Virtual Device for Bluetti devices (need an ESP32)

Hi, i created a method for interfacing a Bluetti power station with Homey.
You need an esp32 with a firmware can bridge bluetooth data to json data
You can use it for reading value from your power station and populate a virtual device created with Device Capabilities app.
I have tested it with an bluetti AC200Max and a battery pack
Actually it only read some info.

Prerequisites:

Step 1: Create a homeyscript for get the power station data (example bluetti_bridge.js)

const b_ip = 'YOUR_ESP32_BRIDGE_IP';
const b_baseurl = 'http://'+ b_ip + '/getData';

function toFixed(num) {
  return Math.trunc((num / 1000) * 100) / 100;    
}

function toFixed2(num) {
  return Math.trunc((num * 100) / 100);    
}

let bluetti = { 'solar_power': '-1', 'home_power': '-1', 'grid_power': '-1', 'battery': '-1', 'ac': 0, 'dc': 0, 'batteries': { 'main': '-1', 'one': '-1', 'two': '-1'} };
try {
  const res = await fetch(b_baseurl);
  if (res.ok) {
    // Get the body JSON
    const data = await res.json();
    //log(data)
    if (data != null) {      
      if (data['dc_input_power'] != null) bluetti.solar_power = toFixed(data['dc_input_power']);
      if (data['ac_output_power'] != null) bluetti.home_power = toFixed2(data['ac_output_power']);
      if (data['ac_input_power'] != null) bluetti.grid_power = toFixed2(data['ac_input_power']);      
      if (data['total_battery_percent'] != null) bluetti.battery = toFixed2(data['total_battery_percent']);
      if (data['pack_battery_percent'] != null) {
        bluetti.batteries.main = toFixed2(data['pack_battery_percent']);
        bluetti.batteries.one = toFixed2((data['total_battery_percent']*2) - data['pack_battery_percent']);
      }
      if (data['ac_output_on'] != null) bluetti.ac = toFixed2(data['ac_output_on']);
      if (data['dc_output_on'] != null) bluetti.dc = toFixed2(data['dc_output_on']);      
    }
  }
} catch (err) {
  bluetti = { 'solar_power': 0, 'home_power': 0, 'grid_power': 0, 'battery': 0, 'ac': 0, 'dc': 0 };
}

if (bluetti.solar_power != '-1') await tag('bluetti_data_solar_power', bluetti.solar_power);
if (bluetti.home_power != '-1') await tag('bluetti_data_home_power', bluetti.home_power);
if (bluetti.grid_power != '-1') await tag('bluetti_data_grid_power', bluetti.grid_power);
if (bluetti.battery_percent != '-1') await tag('bluetti_data_battery', bluetti.battery);
if (bluetti.batteries.main != '-1') await tag('bluetti_data_battery_main', bluetti.batteries.main);
if (bluetti.batteries.one != '-1') await tag('bluetti_data_battery_one', bluetti.batteries.one);
if (bluetti.ac != '-1') await tag('bluetti_data_ac', bluetti.ac);
if (bluetti.dc != '-1') await tag('bluetti_data_dc', bluetti.dc);
     
//log(bluetti);
return true;

Step 2: Create a Virtual Device for your Bluetti power station

  • With app or my.homey.com create a new “Device capabilities” device.

Step 3: Configuring Device Settings

  • Define the capabilities your virtual device will have, you could also import this sample [TEF] String
[tef:AVD:"H4sIAAAAAAACA42Wa4+qOhSG/8qkyfk0TkBuosn5IPUy6iDe0Tk52SmlXBQotkXRnf3fd9wzszFz5wuhq2ut931YTfoT+OQQYzLANAMtcK/xQfvpgW1ttVi4t9i2YLNZx+FiX991zpNbn7lcdOolGpkY0xSvp/mgMfA3kKcS086LEdyPR3yx2Emyaeuaqgo1Gxdi8rjWbCF1lh3Zlg6LM4kSSTQ8Km/UyYjXnU2b3XZxfZKq5vjBVtDy0ZQybT04mIqBvOT2YZPsXBfOcNnYTOPeFutnb6Iz/fGQKMGpPJ7PnVk8ZNN+Lk2aXrHPqL+TIjfZl3lwvymDvmC3cnEaiYaiRwZ74CtnIyXQPm6znaUk/mh0gshx+9NuOC8jK5QeYne6WG17/vp+g6zwNJQhc8MQzps89DoK4ZPBIO8Xkb9coul0Ex1nqWuPdr1whuyhFdUtaG/scGjdd8OyHZEhNPcdG5aRs19yZDu79pL45d6y5uwRKtRYzvRYt/bY2ONuv2Mu4q1yEsnQ7piRMiGNZQgxa670AEqPinMw1qywH4UISl8ssROlw+nAkg6lMIvC3Y23hhLVh2x5srLpcGVC6EF3uCn3Wt73osl6L/f7W9eV5+f7+MiSATxiIejQ9aL7pi3FltdNVvMZamYhgpSXiN+64V5Otz2NFF2LyI7ebRvJobNydrP+mo52abi19mqTqqEkH/Xdw9R2zLYyDvIGT3e5OqX2qpPt6ttiXEpr7p9T1JRhb3JO5054YtvTwFHWh/H2oKUTL5Do2O15dcPcdNrt9r+gBnDBBU0vM8pB6+evGqAsDuMMJQMftEDTV0gT1dW7wGvgO82oN+9Mlch3SJYD3fBwoPsNUAOcCBFn4aUCIBlh4enHASUF+XEpK1AmQCsrkqQGsiL1CHOCBSlFLyaJz0FLrpbHf94vAaMKWJQmBGXvpFiFEPRvoF4FIEoJQ1cZOOGgBaiICAMv2+pjlBLQAhCxGKMbH90wIkgVnpMcMSQIRDny4iQWMeGgFaCEk2pPRI/tS+mUIF4w8iOnx+sWkBEkSC+hR4jYRYtgRZW9zGJxSXarhA7BcYqSazvPRRYofN39KTDIeBxG4rU2J3iI+TXonHLxBBm0dOPp+/KjVU1rNBs1IGge48uCYRqNv/yVZ0oWEoKwGN0IKlBSYVK+gUl5g8n7U+1UVXlB8U+19JFt5bXta6bKp8SVd/CqzwYnjPrFOaYZueE0QayyqH7DovrGIi4YI5moqrzX++0EqJ8aUD+Con4GRZ2RICFYgBa4HFiBRMFfpv9vY+3lONCMFym9wYijKvgNBNqXCLRPvWlvYWjvMNM+QqB9hkB/PcY5izMc59ejrH/DpP7lKOtvR1l/x4bxWhAnmGY+YnFF3fiGIONLQcZbQcaVoF+157vKs6A2VGTZRiWoAQRa//3/6zccbzq6zAgAAA==":/tef]

Step 4: Populate the virtual device with a flow

This is a implementation sample, you can suggest optimization or fix :slight_smile:

How do you get this working with AsyncElegantOTA deprecated?

Hi, i have only forked an existent project and add some things, elegantota are in main project

This are my first esp32 experience… Now i known more the ambient and i can rewrite project

I have update project and removed deprecated libraries

Any progress here? I’ve a Bluetti AC180P and I’m trying to communicate with it through an ESP32. Tried different things with help of AI but cann’t get it working. Can anyone help me?

Thanks in advance

You def should check out the current ESPhome Controller app.
De developer is very helpful and keen on getting things to work.

Thanks, I’ll do that.

For anyone finding this thread: there is now a native community app for BLUETTI — no ESP32 needed for units that are connected to Wi-Fi in the BLUETTI app.

It reads battery level, solar/grid input, AC/DC output and remaining time through the BLUETTI cloud (with real-time updates), can switch AC/DC outputs, and has an optional Bluetooth fallback for when Wi-Fi or the cloud is down.

So far it’s only tested with an Elite 30 V2. Units that only have Bluetooth (no Wi-Fi) aren’t supported yet. @Pappiedappie, if your AC180P is on Wi-Fi in the BLUETTI app, it would be great to hear whether it shows up.

Hallo Gabriel,

Sadly the BLUETTI AC180P has nog WiFi on board. It should made it a lot easier for me. So far no succes for getting usefull information extracting from the BLUETTI :slightly_smiling_face::slightly_smiling_face:

Hi Pappiedappie,

Thanks for checking! That explains it. Pairing in this app goes through the BLUETTI cloud, and the AC180P never shows up there without WiFi.

The good news: the app already has a read-only Bluetooth fallback that handles BLUETTI’s encrypted protocol, and the AC180P appears to use the same register layout as the Elite 30 V2. What’s missing is a way to pair a device over Bluetooth only, without the cloud. That would give you battery level, input/output power and time remaining. You wouldn’t be able to switch the outputs on or off.

I can’t test it myself since I don’t own an AC180P. Would you be willing to try a test version if I add Bluetooth-only pairing? Your Homey would need to be within Bluetooth range of the AC180P, and the BLUETTI phone app must not be connected to it at the same time.

Cheers,
Gabriel

Hello Gabriel, thanks for your answer. That’s great, I really like to do that. There’s only a small issue, I’ve little time due to my work currently. That’s also the reason I stopped with my project with the ESP32. If you don’t mind the time, then I’m sure willing to help you with that.