Hi!
I’m writing this post because I’d like to share one of the IoT projects I have recently been working on: a Python application to discover, monitor and control a NetFlame stove directly from the local network.
First of all, I want to give some context about this project.
Many connected appliances include their own mobile application or web interface, but integrating them with other systems or creating a custom interface is not always easy.
In this case, the stove includes a network controller that exposes a local HTTP interface. My objective was to understand how this interface works and build an independent application around it, without modifying the stove firmware or its internal electronics.
The result is netFlameIoT, an open-source Python project that automatically finds the stove on the network, communicates with its controller and displays its current state in a graphical desktop interface.
The project
The project is divided into four main components:
- A local network scanner
- A generic HTTP client for stove controllers
- A high-level NetFlame API
- A graphical application developed with PySide6
This separation was important because I did not want all the device communication, interface logic and network discovery to be mixed into a single application.
Instead, each layer has a specific responsibility and can potentially be reused independently.
The complete communication flow is:
- Scan the configured local network.
- Find the stove using its MAC address.
- Create an authenticated HTTP client.
- Verify that the device responds correctly.
- Start periodic polling.
- Convert the raw response into structured data.
- Send a snapshot of the device state to the graphical interface.
Finding the stove on the network
One of the first problems was that the stove could receive a different IP address from the router.
Using a fixed IP address in the application would therefore work only until the DHCP lease changed.
To solve this, I created a small LAN scanner based on nmap.
The scanner performs a ping scan over a configurable CIDR range and extracts the IP address, MAC address, hostname and manufacturer information for every detected device.
The application then compares the discovered MAC addresses with a reference MAC configured by the user.
If the stove is not found, the application waits and repeats the discovery process. By default, a new attempt is performed every five seconds.
There is also a fallback mechanism for environments where nmap cannot obtain the MAC address. In that situation, the application tries to establish a real connection with each active IP address and checks whether the device responds like a compatible stove controller.
Once the stove has been identified, the discovery process stops and regular device polling begins.

Communicating with the controller
The stove controller exposes a CGI endpoint that receives HTTP POST requests.
Each request contains an operation identifier called idOperacion, together with any additional parameters required by the operation.
For example, one operation reads the complete stove status, while other operations change the power state, temperature setpoint, power level or operative mode.
I created a generic StoveClient class to handle this communication.
The client supports:
- HTTP Basic authentication
- HTTP Digest authentication
- Unauthenticated connections
- Persistent HTTP sessions
- Configurable request timeouts
- Automatic retries after transport errors
- Operations with additional parameters
- Parsing of firmware error codes
The response returned by the controller is not JSON. Instead, it consists mainly of text lines using a key=value format.
The client parses these lines and converts them into a structured response containing the operation identifier, returned parameters, error code and original raw response.
This transport layer is intentionally independent from NetFlame-specific operation codes, making it possible to reuse it with other compatible stove controllers.
The NetFlame API
On top of the generic HTTP client, I implemented a higher-level NetFlame class.
This class knows the operation identifiers and parameters expected by the device firmware and provides simpler methods such as:
get_data()get_alarms()get_hour()power_on()power_off()increase_temperature()decrease_temperature()increase_power()decrease_power()set_temperature_mode()set_power_mode()
The raw values returned by the firmware are also converted into typed Python models and human-readable descriptions.
For example, the internal stove state is translated into states such as:
- Powered off
- Preheating
- Starting combustion
- Running
- Shutting down
- Waiting for program loading
- Alarm state
The same approach is used for operative modes and alarm codes.
This mapping keeps firmware-specific numbers outside the graphical interface and makes the rest of the application much easier to understand.
The API also applies limits before changing certain values. The temperature setpoint is constrained between 12 and 40 °C, while the power setting is constrained between levels 1 and 9.

The graphical application
The desktop interface was developed using PySide6.
I wanted the application to resemble a modern thermostat rather than a conventional configuration utility.
The main screen displays:
- Current room temperature
- Temperature setpoint
- Stove state
- Operative mode
- Current power level
- Device alarms
- Stove date and time
- Discovered IP address
- Power control
- Temperature or power adjustment
- Mode selection
The central thermostat contains two circular indicators. One represents the configured temperature and the other represents the current measured temperature.
The application also includes an animated power switch and a row of indicators for power levels 1 to 9.
In the current version, this numbered row highlights the active power level. Directly selecting a level from the row is not yet connected to the network worker, so power changes are currently performed using the increase and decrease controls.

Keeping the interface responsive
Network access must never block the graphical interface.
For this reason, all device discovery, HTTP communication and polling are handled by a dedicated Qt worker running in a separate QThread.
Two QTimer objects control the worker:
- A discovery timer that searches for the stove
- A polling timer that periodically reads its state
By default, the stove is polled once per second after the connection has been established.
Communication between the worker and the interface is implemented using Qt signals.
The worker sends connection events and immutable stove snapshots to the interface. In the opposite direction, the interface emits high-level requests when the user changes the temperature, power state or operative mode.
User commands are placed in a thread-safe queue and processed by the worker during the polling cycle.
This prevents concurrent HTTP requests and ensures that the UI thread never communicates with the stove directly.
Connection recovery
Another important part of the project was handling connection failures.
The stove may temporarily disappear from the network because of a Wi-Fi interruption, a device restart or a router configuration change.
If a polling operation fails, the worker:
- Reports the disconnection to the interface.
- Stops the polling timer.
- Removes the existing client.
- Clears the stored IP address.
- Restarts the discovery process.
This allows the application to recover automatically when the stove becomes available again, even if it receives a different IP address.
Results
The final result is a local application capable of discovering and controlling the stove without requiring a fixed IP address.
The interface receives a complete device snapshot every polling cycle and updates the temperature, setpoints, state, mode, power and alarm information.
Separating the application into independent layers also produced another useful result: the graphical interface is only one possible frontend.
The same NetFlame API could later be reused from:
- A command-line utility
- A web service
- A Home Assistant integration
- An MQTT gateway
- A mobile application
- A home automation controller
One of the most important lessons from this project was that communicating with an IoT device is only one part of the solution.
A reliable application must also handle discovery, authentication, response parsing, device-specific states, reconnection and concurrency.
Current limitations
The project is currently focused on Debian and Ubuntu systems.
The LAN scanner depends on nmap and currently expects it to be available at /usr/bin/nmap.
The connection information is also stored in a Python configuration file containing the reference MAC address, network range, username and password.
For this reason, the configuration file should not be committed to a public repository or shared with real credentials.
The application is intended for use on a trusted local network. The current controller communicates over HTTP, so I would not recommend exposing its interface directly to the Internet.
Another current limitation is that the timezone used to display the stove clock is configured for Europe/Madrid. This should become configurable in a future version.
The project source code is available here: