Skip to content

Getting Started

Parker Hawke edited this page Sep 10, 2022 · 2 revisions

Getting Started

Dyson4J takes a simple approach to creating and connecting to a Dyson fan through the use of the DysonFan interface and StandardDysonFan implementation. Before creating an instance, you must get the local network IP address, username, and wifi password of the fan to which you wish to connect. You will also need to know the product code. The latter three values can be found on the front sticker of your Dyson fan as identified below.

Dyson fan sticker with credentials

public final class Main {

    /*
     * You can get the address through the router or other network tools. The device's MAC address is also
     * identified on the fan's sticker label. This will differ from network to network.
     */
    private static final String DEVICE_ADDRESS = "192.168.0.180";
    private static final String USERNAME = "DYSON-XXX-XX-XXXXXXXX"; // The "DYSON-" prefix is actually optional and automatically stripped from the username
    private static final String PASSWORD = "xxxxxxxxxx";

    public static String main(String[] args) {
        DysonFan dysonFan = new StandardDysonFan(
            FanModel.DYSON_PURE_HOT_COOL_LINK_TOWER, // This will depend on the "product code". See below for a list of models
            InetAddress.getByName(DEVICE_ADDRESS),
            new DysonFanCredentials(USERNAME, PASSWORD) // Create a DysonFanCredentials instance using the username and password
        );
    }

}

That's it! You now have access to a Dyson fan.

Connecting To The Fan

Before any queries can be made to the fan, it must first be connected to. This is as simple as calling DysonFan's connect() method and optionally providing a timeout period.

public final class Main {

    private static final String DEVICE_ADDRESS = "192.168.0.180";
    private static final String USERNAME = "DYSON-XXX-XX-XXXXXXXX";
    private static final String PASSWORD = "xxxxxxxxxx";

    public static String main(String[] args) {
        DysonFan dysonFan = new StandardDysonFan(
            FanModel.DYSON_PURE_HOT_COOL_LINK_TOWER,
            InetAddress.getByName(deviceAddress),
            new DysonFanCredentials(username, password)
        );

        System.out.println("Connecting!");

        // The time is optional. Calling dysonFan.connect() without arguments will default to 5 seconds.
        dysonFan.connect(10, TimeUnit.SECONDS).whenComplete((fan, e) -> { // connect() returns a CompletableFuture for when the connection is done
            // "fan" is the same DysonFan instance for convenience, and "e" is a possible exception. We need to check for this
            if (e != null) {
                e.printStackTrace();
                return;
            }

            // Beyond this point, we're connected! We can operate on "fan"!
            System.out.println("Connected!");
        });
    }

}

Dealing With Asynchronous Nature

You'll notice when running the above snippet that "Connected!" is never actually printed to the system output. The reason for this is because Dyson4J is asynchronous in nature and does not keep the JVM running with its threads. In most situations where Dyson4J is expected to be used, this should not be an issue and other processes would keep the program alive. However, in cases like this where the JVM is doing nothing else aside from making Dyson4J calls, we need to make sure the JVM continues to run until it's done doing what needs to be done. We can do this using an AtomicBoolean from the standard library and using a while loop to keep the process running until we tell it to stop.

public final class Main {

    private static final String DEVICE_ADDRESS = "192.168.0.180";
    private static final String USERNAME = "DYSON-XXX-XX-XXXXXXXX";
    private static final String PASSWORD = "xxxxxxxxxx";

    public static String main(String[] args) {
        DysonFan dysonFan = new StandardDysonFan(
            FanModel.DYSON_PURE_HOT_COOL_LINK_TOWER,
            InetAddress.getByName(deviceAddress),
            new DysonFanCredentials(username, password)
        );

        AtomicBoolean terminate = new AtomicBoolean(false);
        System.out.println("Connecting!");

        dysonFan.connect().whenComplete((fan, e) -> {
            if (e != null) {
                e.printStackTrace();
                terminate.set(true); // We can terminate now
                return;
            }

            System.out.println("Connected!");
            terminate.set(true); // We can terminate now
        });

        while (!terminate.get()); // This loop will continue to run indefinitely until we tell it to
    }

}

And now when running the above snippet, you should see both "Connecting!" and "Connected!" (or an error if something is misconfigured), followed shortly by the JVM exiting normally.

Final Steps

Before calling this program complete, it's good practice to disconnect from the fan using the disconnect() method so that we sever all ties with it once we're done. In this case the JVM will terminate all connections upon close anyways, but it's still good to do this as a general rule of thumb. Disconnection to Dyson fans is also asynchronous, however because we don't care too much about disconnecting asynchronously (in this specific situation), we can call .get() on the returned CompletableFuture to make it a blocking operation.

public final class Main {

    private static final String DEVICE_ADDRESS = "192.168.0.180";
    private static final String USERNAME = "DYSON-XXX-XX-XXXXXXXX";
    private static final String PASSWORD = "xxxxxxxxxx";

    public static String main(String[] args) {
        DysonFan dysonFan = new StandardDysonFan(
            FanModel.DYSON_PURE_HOT_COOL_LINK_TOWER,
            InetAddress.getByName(deviceAddress),
            new DysonFanCredentials(username, password)
        );

        AtomicBoolean terminate = new AtomicBoolean(false);
        System.out.println("Connecting!");

        dysonFan.connect().whenComplete((fan, e) -> {
            if (e != null) {
                e.printStackTrace();
                terminate.set(true);
                return;
            }

            System.out.println("Connected!");
            terminate.set(true);
        });

        while (!terminate.get());

        // We're going to synchronously disconnect now that we're past the termination loop
       dysonFan.disconnect().get();
       System.out.println("Disconnected!");
    }

}

And that's it. You've successfully connected to and disconnected from a Dyson fan using Dyson4J!

Product Codes To FanModel

Every fan has a product code on the front of the fan's label. The correct FanModel value must be used as it's required by the fan's MQTT server. If the incorrect model is provided to the StandardDysonFan instance, the connection will fail.

Product Code FanModel
475 DYSON_PURE_COOL_LINK_TOWER
469 DYSON_PURE_COOL_LINK_DESK
455 DYSON_PURE_HOT_COOL_LINK_TOWER
N223 DYSON_360_EYE
438 DYSON_PURE_COOL
358 DYSON_PURE_COOL_HUMIDIFY
520 DYSON_PURE_COOL_DESKTOP
527 DYSON_PURE_HOT_COOL

(internal documentation is not API. You may use this if you wish to create your own library).

Clone this wiki locally