Dinotec Pool dosing system

Hello,
I have a Dinotec dosing system for my pool. The PH value, the chlorine value and the temperature are regulated. The system has WiFi and the data is sent to the Dinotec Cloud. I can access the data using the mobile phone app. Unfortunately I can’t find a Homeassistant addon. Only 3 values ​​would have to be transferred to Homeassistant.

System: Dinotec CF Control 100.

Web

Flyer

What options do I have to get the values ​​in Homeassistant or can someone help me?

I have an Android APK file that I can deploy

Thank you very much, regards Stefan

Hey Stefan,

I have the same requirement. Any luck with your quest sofar?

regards,

Theo

Hello, I haven’t had any luck yet.
How difficult is it to develop an application that logs into a cloud and queries 3 values. Regards Stefan

Hello,

Any chance there is an update for this? I’m also very much interested in adding my Dinotec Pool dosing system to home assistant. I did a little bit of digging (unfortunatelly this is way out of my comfort zone) and found that the data is basically retrieved by an API call that looks like this:

wss://remote.dinotec.de:3006/socket.io/?auth_token=eyJ0eXAiOiJ[...]ok&EIO=3&transport=websocket&sid=gjJ2[...]

Response will look like this:
{"7":231,"8":1200,"38":7,"39":1,"40":16,"41":43,"48":0,"49":1,"66":702,"67":718,"68":2048,"69":0,"85":0,"86":587,"87":11,"o":1,"RSSI":-86,"device":"onhEPSHfqJ7kWswy",o:1}

67 is most likely pH value, 66 Redox.
40 and 41 might be the system time.
85 probe voltage, 86 probe slope

So it feels like there is a chance to get these values and for an experienced developer it might be pretty easy. Does anybody know how to set this up?

Sascha

I think I got it to work. It took a long debate with ChatGPT, but here are the final cleaned up instructions:

:swimming_man: Dinotec to Home Assistant via WebSocket and AppDaemon (Full Guide)


:package: 1. Install the AppDaemon Add-on

  1. In Home Assistant:
  • Go to Settings > Add-ons > Add-on Store
  • Search for AppDaemon and install it
  1. In the AppDaemon settings:
  • Enable Start on boot
  • Enable Show in sidebar (optional)
  1. Start the AppDaemon add-on
  2. Open the Log tab and confirm you see:
INFO AppDaemon: You are now ready to run Apps!

:mag: 2. Locate the apps Folder

The AppDaemon apps folder is located at:

/config/appdaemon/apps

:paperclip: Tip: If it does not exist, see this helpful thread.


:snake: 3. Install python-socketio (Client Library)

You must add the dependency in AppDaemon’s config to make WebSocket connections.

  1. Go to Settings > Add-ons > AppDaemon > Configuration
  2. Update it to include:
system_packages: []
python_packages:
  - "python-socketio[client]"
init_commands: []
  1. Click Save
  2. Go to the Info tab and Restart AppDaemon

This installs python-socketio into the AppDaemon container.


:brain: 4. Create the Dinotec WebSocket Script

  1. In /config/appdaemon/apps/, create a file: dinotec.py
  2. Paste the following:
import appdaemon.plugins.hass.hassapi as hass
import socketio
import logging

class DinotecClient(hass.Hass):

    def initialize(self):
        # Enable debug logging for troubleshooting
        logging.getLogger('socketio').setLevel(logging.DEBUG)
        logging.getLogger('engineio').setLevel(logging.DEBUG)

        self.log("Starting Dinotec WebSocket Client")
        self.sio = socketio.Client()

        # Handle successful connection
        @self.sio.event
        def connect():
            self.log("Connected to Dinotec")
            client_id = "onhEPSHfqJ7kWswy"  # Replace if dynamic
            self.sio.emit("subscribe-dinoaccess", client_id)
            self.log(f"Sent subscribe-dinoaccess event with client_id: {client_id}")

        # Handle disconnection
        @self.sio.event
        def disconnect():
            self.log("Disconnected from Dinotec")

        # Handle the incoming data and create sensors
        @self.sio.on("dinoaccess-status")
        def handle_dinoaccess(data):
            self.log(f"Received dinoaccess-status: {data}")

            # Mapping from data keys to human-readable sensor names
            sensor_map = {
                "7": ("Pool Temperature", 0.1, "°C"),
                "66": ("Pool Redox", None, "mV"),
                "67": ("Pool pH", 0.01, None),
                "85": ("Pool pH Probe Voltage", None, "mV"),
                "86": ("Pool pH Probe Slope", None, None),
                "87": ("Pool pH Probe Zero Point", None, "mV"),
            }

            for key, value in data.items():
                if str(key) in sensor_map:
                    friendly_name, multiplier, unit = sensor_map[key]
                    entity_id = "sensor." + friendly_name.replace(" ", "_").lower()
                    self.log(entity_id)
                    attributes = {"friendly_name": friendly_name}
                    if unit is not None:
                        attributes["unit_of_measurement"] = unit
                    if multiplier is not None:
                        value *= multiplier

                    self.set_state(entity_id, state=value, attributes=attributes)

        # Attempt to connect to the WebSocket server
        try:
            self.sio.connect(
                f'https://remote.dinotec.de:3006/socket.io/?auth_token={self.args["auth_token"]}&EIO=3',
                transports=['websocket']
            )
        except Exception as e:
            self.log(f"Connection failed: {e}")

:gear: 5. Create or Update apps.yaml

  1. In the same folder (/config/appdaemon/apps/), create a file (or update): apps.yaml
  2. Paste this, replacing the token:
dinotec:
  module: dinotec
  class: DinotecClient
  auth_token: "your_valid_token_here"

:bulb: The auth_token is a long JWT you copy from your browser dev tools when logged in to Dinotec.