Controlling Mobius enabled VorTech pump using 0-10V (and BLE)

I figure if I can emulate a device, I should be able to issue commands to whatever device in the tank I want to even if I'm not directly connected to it.
I think this is the basic premise of how the mxm operates. One thing you should focus on is having it relay time and date corrections to all radion lights on a time interval to see if you can solve the major flaw that plagues mobius and correct the issue of the lights turning on in the middle of the night and not turning on when they're supposed to.

I don't know how complex your getting. But maybe consider adding time keeping hardware that can handle parent/child, sync/anti-sync timing to the 10ms range so that people can experience precise motor movements to get back the "standing wave" function with multiple vortechs.

And finally, I hope you're planning to put this out for free, otherwise it'll never amount to anything.
 
Interested to see if similar control can be had for the Versa dosers…I have plenty of esp32s and ecotech products if you want someone to help you test or give telemetry data
 
I think this is the basic premise of how the mxm operates. One thing you should focus on is having it relay time and date corrections to all radion lights on a time interval to see if you can solve the major flaw that plagues mobius and correct the issue of the lights turning on in the middle of the night and not turning on when they're supposed to.

I don't know how complex your getting. But maybe consider adding time keeping hardware that can handle parent/child, sync/anti-sync timing to the 10ms range so that people can experience precise motor movements to get back the "standing wave" function with multiple vortechs.

And finally, I hope you're planning to put this out for free, otherwise it'll never amount to anything.

Firstly, that's the exact reason I started working on deciphering the attribute values on some Radion lights. I've actually done quite a bit of investigation into that issue and I'm fairly convinced there is some section of the firmware that is using incorrect endianness. I would love to be able to offer some kind of a solution at the end of all this.

Secondly, that's the exact reason I started work on this library. I thought I could sync/anti-sync with my brand new MP40s and MXM and realized I couldn't. Thus, this hope was born.

And of course! Gotta keep it open source! There's literally no reason to make this without it being freely available. Only reason I haven't shared the repo publicly is that it's still a WIP, requires Flash memory for storing data, and if I have to reorganize how data is stored, I don't want to screw up previous installs.
 
Interested to see if similar control can be had for the Versa dosers…I have plenty of esp32s and ecotech products if you want someone to help you test or give telemetry data

Definitely happy to work with you on that. I've got a database of hardware IDs associated with device types I used by fuzzing against the Mobius app. All devices store their schedules pretty similarly, so I'm sure we can get it figured out. My time has been very limited lately but it's super close! :)
 
Any update? I'm looking forward to control my Mobius devices with external control... I have a couple of MP10 and Nero 3 to test it out if needed... Thank you!
 
Any update? I'm looking forward to control my Mobius devices with external control... I have a couple of MP10 and Nero 3 to test it out if needed... Thank you!
Been a rough year, got distracted with life things and haven't had any Mobius devices on my tank in a minute, though I still have them around. I'll get back to this ASAP!
 
With the help of ChatGPT I'm slowly going on, now I have a fully Atom Lite controlling my 2 MP10 via serial terminal.
Next step is to add MQTT support to have control in Home Assistant. Here I send you the arduino code for the Atom Lite and the updated MobiusBLE libray

Code:
#include <ArduinoBLE.h>
#include <MobiusBLE.h>
#include <FastLED.h>

/* ====== M5 ATOM LITE ====== */
#define LED_PIN    27        // LED RGB integrato
#define NUM_LEDS   1
#define LED_TIMEOUT 5000     // ms: torna bianco se nessun comando

CRGB leds[NUM_LEDS];

/* ====== MOBIUS DEVICES ====== */
MobiusDevice pump1;
MobiusDevice pump2;

/* ====== UTILITY LED ====== */
void setLed(const CRGB &color) {
  leds[0] = color;
  FastLED.show();
}

/* ====== LED TIMEOUT ====== */
unsigned long lastCommandTime = 0;
CRGB lastLedColor = CRGB::White;

void setup() {
  Serial.begin(115200);

  /* LED init */
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(40);

  setLed(CRGB::White);   // Pronto / inizializzazione

  /* BLE init */
  if (!BLE.begin()) {
    setLed(CRGB::Red);
    Serial.println("BLE init failed!");
    while (1);
  }

  /* Scan Mobius devices */
  String addresses[5];
  int count = 0;
  Serial.println("Scanning for Mobius devices...");
  while (count < 2) {
    count = MobiusDevice::scanForMobiusDevices(addresses);
    delay(1500);
  }

  Serial.println("Devices found:");
  for (int i = 0; i < count; i++) {
    Serial.println(addresses[i]);
  }

  pump1 = MobiusDevice(addresses[0]);
  pump2 = MobiusDevice(addresses[1]);

  /* Reset BLE stack */
  BLE.begin();

  setLed(CRGB::White);  // Pronto
  Serial.println("Ready. Send scene numbers via Serial (e.g., 1, 2, 3...)");
}

void loop() {
  // Controllo se c'è un numero sulla seriale
  if (Serial.available()) {
    String line = Serial.readStringUntil('\n');
    line.trim();
    if (line.length() > 0) {
      int sceneId = line.toInt();
      Serial.print("Sending scene: ");
      Serial.println(sceneId);
      sendSceneToPumps(sceneId);
      lastCommandTime = millis(); // reset timeout
    }
  }

  // Controllo timeout LED
  if (millis() - lastCommandTime > LED_TIMEOUT && lastLedColor != CRGB::White) {
    setLed(CRGB::White);  // Torna pronto
    lastLedColor = CRGB::White;
  }
}

void sendSceneToPumps(int sceneId) {
  setLed(CRGB::Yellow); // Invio comandi
  lastLedColor = CRGB::Yellow;

  bool p1ok = false;
  bool p2ok = false;

  /* ====== POMPA 1 ====== */
  if (pump1.connect()) {
    p1ok = pump1.setScene(sceneId);
    int currentScene = pump1.getCurrentScene(); // Legge la scena corrente
    Serial.print("Pump1 scene set to: ");
    Serial.println(currentScene);
    delay(120);             
    pump1.disconnect();
  }

  /* ====== POMPA 2 ====== */
  if (pump2.connect()) {
    p2ok = pump2.setScene(sceneId);
    int currentScene = pump2.getCurrentScene(); // Legge la scena corrente
    Serial.print("Pump2 scene set to: ");
    Serial.println(currentScene);
    delay(120);             
    pump2.disconnect();
  }

  /* ====== LED STATUS ====== */
  if (p1ok && p2ok) {
    setLed(CRGB::Green);  // Comandi confermati
    lastLedColor = CRGB::Green;
    Serial.println("Both pumps OK");
  } else if (p1ok || p2ok) {
    setLed(CRGB::Yellow); // Parziale
    lastLedColor = CRGB::Yellow;
    Serial.println("Partial success (1/2)");
  } else {
    setLed(CRGB::Red);    // Errore
    lastLedColor = CRGB::Red;
    Serial.println("Failed (0/2)");
  }

  lastCommandTime = millis(); // reset timeout
}
 

Attachments

Thanks to @mard and the others for driving the beginnings of this project. I've started to convert the ESP32 Arduino code into a standalone Python library where I will then write a Home Assistant integration. My goals are to have granular speed control over the Vortech, Axis, and Nero pumps directly in Home Assistant without needing an ESP32 or the Neptune MXM in the middle. I'm glad I ran across this project because I spent the past two days doing BT packet dumps trying to guess the CRC. I can't say I'll make significant progress very quickly, but I'll post update as I have them.
 
BT packet dumps trying to guess the CRC
Ha. Thats the hardest part. I cracked the crc for the versa, which i'm sure its the same. If I remember correctly it was one used by IBM for their floppy discs way back in the day.

If i had known these guys did it 1st, it would've saved me days.
 
Tagging along for this, everything else in my house is automated. Now all I need is to tell Siri to start feed mode and mission complete.
 
I finished writing a standalone python library (with the help of Grok Build) for the Versa and a companion Home Assistant integration. I have an MXM on my Apex, so I decided to write a fully functional Home Assistant integration that can control the Apex and all MXM connected pumps (Nero, Vectra, Axis, and Vectra). Since the MXM doesn't support the Versa (and I hate the scheduling options in the Mobius app), my Home Assistant integration allows you to define schedules allowing you to dose weekly on any day of the week you want (Monday, Wed, Friday). I don't have any of this published on Github yet, but as soon as I do and have these available in HACS, I'll create a new thread about them and link here. If anyone is interested before then, you can DM me and we can discuss early access.

A teaser screenshot of my "EcoTech Versa BLE" integration showing one of my Versa devices as it is dosing 40mL of Alk solution over 6 hours.

Screenshot 2026-07-14 at 10.52.42 AM.png
 
I finished writing a standalone python library (with the help of Grok Build) for the Versa and a companion Home Assistant integration. I have an MXM on my Apex, so I decided to write a fully functional Home Assistant integration that can control the Apex and all MXM connected pumps (Nero, Vectra, Axis, and Vectra). Since the MXM doesn't support the Versa (and I hate the scheduling options in the Mobius app), my Home Assistant integration allows you to define schedules allowing you to dose weekly on any day of the week you want (Monday, Wed, Friday). I don't have any of this published on Github yet, but as soon as I do and have these available in HACS, I'll create a new thread about them and link here. If anyone is interested before then, you can DM me and we can discuss early access.

A teaser screenshot of my "EcoTech Versa BLE" integration showing one of my Versa devices as it is dosing 40mL of Alk solution over 6 hours.

Screenshot 2026-07-14 at 10.52.42 AM.png
Great! LLM assisted protocol work - I hadn’t steered any agents to this yet but I’m glad you got this working!
 
I finished writing a standalone python library (with the help of Grok Build) for the Versa and a companion Home Assistant integration. I have an MXM on my Apex, so I decided to write a fully functional Home Assistant integration that can control the Apex and all MXM connected pumps (Nero, Vectra, Axis, and Vectra). Since the MXM doesn't support the Versa (and I hate the scheduling options in the Mobius app), my Home Assistant integration allows you to define schedules allowing you to dose weekly on any day of the week you want (Monday, Wed, Friday). I don't have any of this published on Github yet, but as soon as I do and have these available in HACS, I'll create a new thread about them and link here. If anyone is interested before then, you can DM me and we can discuss early access.

A teaser screenshot of my "EcoTech Versa BLE" integration showing one of my Versa devices as it is dosing 40mL of Alk solution over 6 hours.

Screenshot 2026-07-14 at 10.52.42 AM.png
That’s amazing 😎 so this only works with the Apex MXM module right?
 
That’s amazing 😎 so this only works with the Apex MXM module right?
Sorry, I wasn't clear. I opted to control my Vortech, Nero, and Axis pumps via the Apex MXM module and using the new Apex Home Assistant integration I wrote.

The MXM doesn't support controlling the EcoTech Versa dosing pumps, so I wrote a separate Python library and Home Assistant integration just for those. There is no Apex needed to use the Home Assistant integration for the Versa.
 
Sorry, I wasn't clear. I opted to control my Vortech, Nero, and Axis pumps via the Apex MXM module and using the new Apex Home Assistant integration I wrote.

The MXM doesn't support controlling the EcoTech Versa dosing pumps, so I wrote a separate Python library and Home Assistant integration just for those. There is no Apex needed to use the Home Assistant integration for the Versa.
Outstanding work! The idea that the versa isn't part of the mxm is simply silly.

It shouldn't be our responsibility to develop patches and work arounds. But that's the direction it's been heading for some time now.
 
I think it comes down to low hanging fruit and not caring. Whatever is the easiest to get out the door and generally works for the average non demanding user. I am pretty confident that the MP controllers don't come close to doing what they are programmed to do with mirror mode, and certain other modes. But lights flash and water moves, so most people are happy.
 
Outstanding work! The idea that the versa isn't part of the mxm is simply silly.

It shouldn't be our responsibility to develop patches and work arounds. But that's the direction it's been heading for some time now.

Should be simpler for the original developers to whip it up with LLMs now ;)

(But I imagine they outsourced chunks of this work to a contractor and then the whole product sits in a weird position of "supported" but none of the original creators are attached to it)
 

TOP 10 Trending Threads

Back
Top
Home
Post thread…
Market
What's new