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

Paulo Hanashiro

Community Member
View Badges
Joined
Jun 4, 2013
Messages
51
Reaction score
25
Location
Sydney/Australia
Rating - 0%
0   0   0
I think I make it work... Simply uploading again the software.
If I set the 0-10V pin to a corresponding 5V it triggers the Feed mode on my pump. There's a way to keep the feed mode until the pin is at 5V?
You don't need the ADC to enable feed mode, you can use a simple digitalRead(GPIO) and add a momentary push-button to activate the feed scene like the below:
esp32-button-wiring-diagram.jpg


You could also add more momentary switches to enable other scenes.

As far as I could test, the Feed scene will switch back to normal after the feed timeout you set in Mobius app is reached, so a potential way to keep the feed scene on is to continually set the feed scene so you're always resetting the timeout counter.

rgrds
 

Paulo Hanashiro

Community Member
View Badges
Joined
Jun 4, 2013
Messages
51
Reaction score
25
Location
Sydney/Australia
Rating - 0%
0   0   0
Somehow wasn’t aware of this thread but it does raise the question of “why isn’t there a Home Assistant integration for this”. Even if it’s just feed mode setting.
I guess no one with enough BLE + HA knowledge took the challenge?

I'd say if you run HA on RPi it would be just a matter of writing the python libraries to use the Pi BLE stack to talk to the Mobius devices? As I was able to run a simple python script from my PC's bluetooth adapter to find the Mobius addresses and list their UUIDs.

cheers.
 

theatrus

Valuable Member
View Badges
Joined
Mar 26, 2016
Messages
2,062
Reaction score
3,450
Location
Sacramento, CA area
Rating - 0%
0   0   0
I guess no one with enough BLE + HA knowledge took the challenge?

I'd say if you run HA on RPi it would be just a matter of writing the python libraries to use the Pi BLE stack to talk to the Mobius devices? As I was able to run a simple python script from my PC's bluetooth adapter to find the Mobius addresses and list their UUIDs.

cheers.

I mean I'm not blaming anyone :beaming-face-with-smiling-eyes:

Its all a matter of time - the good thing on the HA front is it has good support for BLE devices directly, including GATT devices which need active connections, as well as using ESP32 devices as bridges to extend reach.
 

Simonv92

Active Member
View Badges
Joined
Oct 21, 2014
Messages
134
Reaction score
102
Location
Italy
Rating - 0%
0   0   0
Thanks all for the reply!
You don't need the ADC to enable feed mode, you can use a simple digitalRead(GPIO) and add a momentary push-button to activate the feed scene like the below:
esp32-button-wiring-diagram.jpg


You could also add more momentary switches to enable other scenes.

As far as I could test, the Feed scene will switch back to normal after the feed timeout you set in Mobius app is reached, so a potential way to keep the feed scene on is to continually set the feed scene so you're always resetting the timeout counter.

rgrds
Thank you for the drawing, I'll do some more test... Yes the best thing would be to have an HA direct integration. But for now I can use a Reef-Pi outlet to control the pin on an Atom Lite board as it's super tiny.
I really don't want to switch ON/OFF the outlet of the MP10 to feed the tank..
 

Paulo Hanashiro

Community Member
View Badges
Joined
Jun 4, 2013
Messages
51
Reaction score
25
Location
Sydney/Australia
Rating - 0%
0   0   0
There you go, please note this is just a proof of concept and was not well tested:


C++:
/*!
 *
 * MQTT interface for Mobius BLE.
 *
 * HA mqtt auto discovery with a switch and a sensor.
 *  Switch is to set the Feed mode
 *  Sensor is to report the QTY of Mobius devices found by the scan feature
 *  it will intercept the switch to set feed mode and set the Normal schedule back
 * 
 *
 * Work in progress
 *
 */
#include <ESP32_MobiusBLE.h>
#include "ArduinoSerialDeviceEventListener.h"

#include "EspMQTTClient.h"
#include <string>
#include "secrets.h"
#include <esp_task_wdt.h>
#include <ArduinoJson.h>

#ifndef LED_BUILTIN
#define LED_BUILTIN 6
#endif

//1 seconds WDT
#define WDT_TIMEOUT 30
#define EXE_INTERVAL 300000

unsigned long lastExecutedMillis = 0; // variable to save the last executed time

// Configuration for wifi and mqtt
EspMQTTClient client(
  mySSID,                // Your Wifi SSID
  myPassword,            // Your WiFi key
  "homeassistant.local", // MQTT Broker server ip
  mqttUser,              // mqtt username Can be omitted if not needed
  mqttPass,              // mqtt pass Can be omitted if not needed
  "Mobius",              // Client name that uniquely identify your device
  1883                   // MQTT Broker server port
);

char* jsonSwitchDiscovery =  "{\
    \"name\":\"Feed Mode\",\
    \"command_topic\":\"homeassistant/switch/mobiusBridge/set\",\
    \"state_topic\":\"homeassistant/switch/mobiusBridge/state\",\
    \"unique_id\":\"mobius01ad\",\
    \"device\":{\
      \"identifiers\":[\
        \"mobridge01ad\"\
      ],\
      \"name\":\"Mobius\",\
      \"manufacturer\": \"xx\",\
      \"model\": \"Mobius BLE Bridge\",\
      \"sw_version\": \"2024.1.0\"\
         }}";

char* jsonSensorDiscovery =  "{ \
    \"name\":\"QTY Devices\",\
    \"state_topic\":\"homeassistant/sensor/mobiusBridge/state\",\
    \"value_template\":\"{{ value_json.qtydevices}}\",\
    \"unique_id\":\"qtydev01ae\",\
    \"device\":{\
      \"identifiers\":[\
        \"mobridge01ad\"\
      ]\
      }\
    }";

bool prevState = false;
bool currState = false;
bool configPublish = false;
bool firstRun = true;

// wifi and mqtt connection established
void onConnectionEstablished()
{
  ESP_LOGI(LOG_TAG, "Connected to MQTT Broker :)");
 
  // Listen for a scene update from mqtt and call the update function
  // May need to do this from the loop(). Test.
  client.subscribe("homeassistant/switch/mobiusBridge/set", [](const String& feedMode) {
    if (feedMode.length() > 0) {
      if (feedMode == "ON") {
        currState = true;
        digitalWrite(LED_BUILTIN, HIGH);
      } else {
        currState = false;
        digitalWrite(LED_BUILTIN, LOW);
      }
      configPublish = false;

      ESP_LOGI(LOG_TAG, "INFO: Update device scene from MQTT trigger: %s\n", feedMode);
    }
  });

}

// Define a device buffer to hold found Mobius devices
MobiusDevice deviceBuffer[20];
int deviceCount = 0;

JsonDocument doc;

void setup() {
  // connect the serial port for logs
  Serial.begin(115200);
  while (!Serial);

  esp_task_wdt_init(WDT_TIMEOUT, true); //enable panic so ESP32 restarts
  esp_task_wdt_add(NULL); //add current thread to WDT watch

  pinMode(LED_BUILTIN, OUTPUT);
  prevState = !currState;
  firstRun = true;

  client.enableDebuggingMessages(); // Enable debugging messages sent to serial output
  client.enableHTTPWebUpdater(); // Enable the web updater. User and password default to values of MQTTUsername and MQTTPassword. These can be overridded with enableHTTPWebUpdater("user", "password").
 
  // Increase default packet size for HA mqtt json messages
  client.setMaxPacketSize(2048);

  // Initialize the library with a useful event listener
  MobiusDevice::init(new ArduinoSerialDeviceEventListener());

  ESP_LOGI(LOG_TAG, "Setup run");
}

void loop() {
  // Wait for mqtt and wifi connection
  while(!client.isConnected()){client.loop();};

  // Loop mqtt
  client.loop();


  // create buffer to store the Mobius devices
  MobiusDevice device = deviceBuffer[0];

  if (!configPublish) {
    //Scan BLE and MQTT Publish the main config only on boot or on status change

    //Scan for Mobius devices
    int scanDuration = 15; // in seconds
    deviceCount = 0;

    while (!deviceCount) {
      //Scan until at least one device is returned
      deviceCount = MobiusDevice::scanForMobiusDevices(scanDuration, deviceBuffer,10);
      ESP_LOGD(LOG_TAG, "INFO: Mobius Devices found: %i\n", deviceCount);
      esp_task_wdt_reset();
    }

    if (!client.publish("homeassistant/switch/mobiusBridge/config", jsonSwitchDiscovery)) {  //This one is for the switch
      ESP_LOGD(LOG_TAG, "ERROR: Did not publish");
    }

    if (!client.publish("homeassistant/sensor/mobiusBridge/config", jsonSensorDiscovery)) { //This is for the QTY
      ESP_LOGD(LOG_TAG, "ERROR: Did not publish");
    }

    configPublish = true;
  }

  /***************************************************************
  ************       BLE Connection starts here       ************
  ***************************************************************/
  //inside the mqtt subscribe function onConnectionEstablished(), it will turn the LED on with digitalWrite(LED_BUILTIN, HIGH);
  //using GPIO to proxy the Mobius Scene.
  bool currState = digitalRead(LED_BUILTIN);

    if (prevState != currState) {
    //If Current state is different from previous, publish MQTT state
    ESP_LOGD(LOG_TAG, "INFO: Publishing state");

    if (currState) {
      //This is Feed Mode
      ESP_LOGD(LOG_TAG, "INFO: LED is ON");
      if (!client.publish("homeassistant/switch/mobiusBridge/state", "ON")) {
        ESP_LOGD(LOG_TAG, "ERROR: Did not publish LED on");
      }
    } else {
      //This is Normal Operation
      ESP_LOGD(LOG_TAG, "INFO: LED is OFF");
      if (!client.publish("homeassistant/switch/mobiusBridge/state", "OFF")) {
        ESP_LOGD(LOG_TAG, "ERROR: Did not publish LED off");
      }
    }

    if (!firstRun){
      // Do not connect to device during boot

      for (int i = 0; i < deviceCount; i++) {
        // connect to each device in buffer to set the new scene
        device = deviceBuffer[i];

        int tries = 1;
        //loop until connected or exit after 10 tries
        while(tries<=10){

          // Get manufacturer info
          std::string manuData = device._device->getManufacturerData();

          // Don't connect unless we have a serial number
          if (manuData.length() > 1){
            // Connect, get serialNumber and current scene
            ESP_LOGI(LOG_TAG, "\nINFO: Connect to device number: %i\n", i);
            if (device.connect()) {

              ESP_LOGI(LOG_TAG, "INFO: Connected to: %s\n", device._device->toString().c_str());

              // serialNumber is from byte 11
              std::string serialNumberString = manuData.substr(11, manuData.length());
              char serialNumber[serialNumberString.length() + 1] = {};
              strcpy(serialNumber, serialNumberString.c_str());
              ESP_LOGD(LOG_TAG, "INFO: Device serial number: %s\n", serialNumber);

              //Get Current scene
              uint16_t sceneId = device.getCurrentScene();

              //Convert scene from int to friendly MQTT text
              char currScene[2];
              sprintf(currScene, "%u", sceneId);
              
              // delaying without sleeping
              unsigned long startMillis = millis();
              while (1000 > (millis() - startMillis)) {}

              /*===============================================
              =====               Set Scene               =====
              ===============================================*/
              if ((sceneId!=1) and (currState) ) {
                //Scene is different from feed mode (1), and Feed switch is ON, set device to feed mode
                device.setFeedScene();
              } else if ((sceneId==1) and !currState) {
                //Scene is feed mode (1), and Feed switch is OFF, set device to Normal Schedule
                device.runSchedule();
              }

              //Disconnect from Mobius Device
              device.disconnect();

              //If connection completed, break the loop
              break;
            }
            else {
              tries++;
            }
          }
        }

        //Print error message if didn't connect after 10 tries
        if (tries>9) {
          ESP_LOGE(LOG_TAG, "ERROR: Failed to connect to device");
        }
      }
    }   

    char cstr[20];
    JsonDocument jsonQtyDev;
    jsonQtyDev["qtydevices"] = deviceCount;
    serializeJson(jsonQtyDev, cstr);

    ESP_LOGD(LOG_TAG, "INFO: Mobius BLE device count: %i\n", deviceCount);
    
      if (!client.publish("homeassistant/sensor/mobiusBridge/state", cstr)) {
        ESP_LOGD(LOG_TAG, "ERROR: Did not publish qtyitems");
      }

    prevState = currState;
  }

  firstRun = false;
 
  esp_task_wdt_reset();
}

you also need to create a secrets.h file with:

#define mySSID "SSID"
// Your WiFi key
#define myPassword "WIFI PASS"
// mqtt username Can be omitted if not needed
#define mqttUser "user"
// mqtt pass Can be omitted if not needed
#define mqttPass "mqtt pass"
 

Managing real reef risks: Do you pay attention to the dangers in your tank?

  • I pay a lot of attention to reef risks.

    Votes: 142 43.0%
  • I pay a bit of attention to reef risks.

    Votes: 117 35.5%
  • I pay minimal attention to reef risks.

    Votes: 50 15.2%
  • I pay no attention to reef risks.

    Votes: 16 4.8%
  • Other.

    Votes: 5 1.5%
Back
Top