Skip to main content

Smart controller WiFi firmware

Only applies to the WiFi firmware option

The VanTurle smart controller is an ESP32-C3 powered upgrade kit, compatible with your Maxxfan®, that exposes much more flexibility than the IR remote or button panel. It can turn the fan off and on, adjust the speed, reverse the direction of rotation, and even measure the current power consumption of the fan.

This manual covers the WiFi firmware stack, which enables a web app, REST API, websocket, MQTT client and Tuya integration. A separate Bluetooth firmware build exists for the Home app on iOS and and a companion app on Android. Only one of these can be on the device at a time, as they use the same hardware resources. Select the one you want during checkout.

Connecting to the controller

When first booted, the controller is in AP mode and hosts a “hotspot” WiFi network that you can connect to for initial setup. Once configured, it switches to STA mode and connects to your local WiFi network, where it can be accessed from any device on the same network. The hotspot network configuration is as follows:

SSID VanTurtle Fan
Password Something like: 0000-0000
Address 192.168.4.1

Connect to this network from a phone or laptop. Most devices will automatically prompt you to open the captive portal, which opens the controller’s web interface directly. If that prompt does not appear, open a browser and navigate to http://192.168.4.1 manually. Take care to go to the http url, and not https.

Once you have the web app open, you should see the slider controls for the fan and be able to set the speed. If all works as it should, you can proceed to the settings (cog icon in the top right) and select the WiFi settings.

Fill in your vans WiFi network name (SSID) and password, then save the settings. The controller should reboot and attempt to connect to your WiFi. If the credentials were correct and the connection is successful, the controller will switch to STA mode. If there was an error connecting to WiFi, it will fall back to AP mode so you can try again.

If your network supports mDNS (most home routers do), the controller will be accessible at http://vanturtle-fan.local. Otherwise you will need to find the IP address assigned to the controller by your router (check its DHCP table) and use that to access the web app.

Using the web app

The main screen shows a vertical slider. Drag it up or down to set the fan speed, or tap a position on the track to jump to that speed. The slider has 10 steps plus an off position at the bottom.

Three buttons sit below the slider:

Auto temp Toggles automatic temperature hold mode.
Open / close Opens or closes the fan lid, even if off.
Reverse airflow Toggles the fan direction between forward and reverse.

When the browser cannot reach the controller the entire remote fades out to indicate the disconnected state. The app reconnects automatically every few seconds. The remote becomes interactive again as soon as the connection is re-established.

When on a mobile device, you can add the web app to your home screen for a more native app-like experience. In Safari, tap the share icon and select “Add to Home Screen”. In Chrome, open the menu and select “Add to Home Screen”. The exact steps may vary depending on your device and browser.

MQTT

The controller can connect to an MQTT broker on your local network (or remote if you really want to) and publish fan state changes to configurable topics, as well as accept commands by subscribing to those same topics. This makes it straightforward to integrate with many systems, including Home Assistant, Node-RED (like on the Victron Cerbo GX), or any other system that speaks MQTT.

MQTT is disabled by default. To enable it, open the settings, go to the MQTT section, and fill in at least the broker address. The controller will connect on next save. Leave the broker address blank to disable MQTT again.

All topics are freely configurable and none are set by default. Only topics with a value entered in the settings are subscribed to or published on. Each topic carries a plain-text value.

Topic Direction Values
Speed Publish & subscribe Integer 110
Direction Publish & subscribe 0 = maybe forward, 1 = maybe reverse
Auto temp Publish & subscribe 0 = off, 1 = on
On/off Publish & subscribe 0 = off, 1 = on
Open/close Subscribe only Any value triggers the action
Voltage Publish only Floating point, e.g. 12.345 (volts)
Current Publish only Floating point, e.g. 1.234 (amps)
Power Publish only Floating point, e.g. 15.678 (watts)
Keepalive Publish only Publishes 1 every 60 seconds

All publish topics use QoS 1. The controller publishes the full fan state immediately after connecting to the broker, so the broker’s retained values are always up to date from the first connection.

When a broker is configured to retain messages, the controller will receive its own last-published values back when it reconnects. Without suppression this can cause the controller to act on its own state reports as if they were new commands. The Echo suppress setting specifies a window in milliseconds during which incoming messages are ignored after the controller publishes. Setting this to around 500 is enough to filter out most self-echoes without delaying legitimate external commands. Set it to 0 to disable.

REST API

The controller exposes a REST API over HTTP on port 80. This section covers the /state endpoint, which reads and controls the fan. To GET the current state:

GET http://vanturtle-fan.local/state

Example response:

{
  "active": true,
  "speed": 6,
  "direction": 0,
  "auto_hold": true,
  "voltage": 12.341,
  "current": 0.874,
  "power": 10.786,
  "has_calibration": true,
  "is_calibrating": false
}
active Whether the fan is running.
speed Current speed level, 1-10.
direction A guess on the airflow direction, don’t trust it.
auto_hold Whether auto-hold is enabled.
voltage Voltage at the fan terminals in volts.
current Current draw in amps.
power Power in watts as reported by the INA226.
has_calibration Whether the controller has been calibrated.
is_calibrating Whether a calibration is currently in progress.

Use the POST endpoint to update one or more fan state fields. Send a JSON body with any subset of the writable fields. Unrecognised fields are ignored. The response is the full updated state, identical in format to the GET response.

POST http://vanturtle-fan.local/state
Content-Type: application/json

{"active": true, "speed": 8}
active Boolean or 0/1. Turns the fan on or off.
speed Integer 1–10. Sets the fan speed. Values outside this range are ignored.
direction Toggles the fan direction. The value does not matter.
auto_hold Boolean or 0/1. Enables or disables auto-hold.

State changes made through the REST API are reflected in the web app and published over MQTT and Tuya in the same way as changes made from any other source.

WebSocket

The controller exposes a WebSocket endpoint at /ws. It carries two things: real-time fan state updates pushed from the controller to all connected clients, and the raw UART log output. The websocket is preferable over polling the REST API for real-time updates, and is required for receiving the log output.

State updates are sent on connect and on every state change. The format is identical to the GET /state response:

{"active":true,"speed":6,"direction":0,"auto_hold":true,"voltage":12.341,"current":0.874,"power":10.786,"has_calibration":true,"is_calibrating":false}

In addition to state, the controller forwards its internal log output to all connected clients. Log frames carry a type field to distinguish them from state updates:

{"type":"log","raw":"I (12345) MQTT: Connected to broker"}

It’s also possible to send commands to the controller over the websocket. Send a JSON text frame with a command field and an optional value. The controller applies the command and broadcasts an updated state to all clients.

Command Value Effect
active Boolean, 0/1, or 2 Turns the fan on or off. Value 2 toggles.
speed Integer 1–10, or "+" / "-" Sets the speed. The string forms increment or decrement by one step.
direction Any (ignored) Toggles the fan direction.
hold Boolean or 0/1 Enables or disables auto-hold.
openclose N/A Triggers a momentary open/close.
get N/A Replies with the current state to this client only, without broadcasting.
calibrate N/A Starts an INA226 recalibration. Has no effect if one is already running.
reset N/A Triggers a factory reset, erasing all stored settings.

For instance, set speed to 7:

{"command":"speed","value":7}