Repository: rytilahti/python-miio (language: python)

Issue:
[meta] Restructure integrations to their own directories
Move each integration to their own directory, containing the integration-specific implementation, data and test files.

This allows separate integrations to have their own data files stored without poluting the main package (see, e.g., #1094 for yeelight spec files), and make the integrations partially self-contained.
This also allows adding integration-specific, discoverable manifest files whose pros are discussed in another issue to be linked here.

Each integration should be stored under `miio/integrations/<name>` which can contain several source files including unit tests and any other data.

### Status

* [ ] Yeelight (#1160)


Discussion / hints:

Fix patch:
diff --git a/docs/device_docs/vacuum.rst b/docs/device_docs/vacuum.rst
index 69e58a78f..3728943d8 100644
--- a/docs/device_docs/vacuum.rst
+++ b/docs/device_docs/vacuum.rst
@@ -306,8 +306,8 @@ so it is also possible to pass dicts.
 `mirobo --help`
 ~~~~~~~~~~~~~~~
 
-.. click:: miio.integrations.vacuum.roborock.vacuum_cli:cli
+.. click:: miio.integrations.roborock.vacuum.vacuum_cli:cli
    :prog: mirobo
    :show-nested:
 
-:py:class:`API <miio.vacuum>`
+:py:class:`API <miio.integrations.roborocok.vacuum>`
diff --git a/docs/device_docs/yeelight.rst b/docs/device_docs/yeelight.rst
index 84c72d108..86704a741 100644
--- a/docs/device_docs/yeelight.rst
+++ b/docs/device_docs/yeelight.rst
@@ -82,4 +82,4 @@ Status reporting
     or an issue, if you do not want to implement it on your own!
 
 
-:py:class:`API <miio.yeelight>`
+:py:class:`API <miio.integrations.yeelight.light>`
diff --git a/docs/simulator.rst b/docs/simulator.rst
index 6504271d9..8cd1e2b44 100644
--- a/docs/simulator.rst
+++ b/docs/simulator.rst
@@ -33,7 +33,7 @@ Usage
 
 You start the simulator like this::
 
-    miiocli devtools miio-simulator --file miio/integrations/fan/zhimi/zhimi_fan.yaml
+    miiocli devtools miio-simulator --file miio/integrations/zhimi/fan/zhimi_fan.yaml
 
 The mandatory ``--file`` option takes a path to :ref:`a device description file <miio_device_descriptions>` file
 that defines information about the device to be simulated.
@@ -180,7 +180,7 @@ Example Description File
 The following description file shows a complete,
 concrete example for a device using ``get_prop`` for accessing the properties (``zhimi_fan.yaml``):
 
-.. literalinclude:: ../miio/integrations/fan/zhimi/zhimi_fan.yaml
+.. literalinclude:: ../miio/integrations/zhimi/fan/zhimi_fan.yaml
    :language: yaml
 
 .. _example_desc_methods:
@@ -191,7 +191,7 @@ Example Description File Using Methods
 The following description file (``simulated_roborock.yaml``) shows a complete,
 concrete example for a device using custom method names for obtaining the status.
 
-.. literalinclude:: ../miio/integrations/vacuum/roborock/simulated_roborock.yaml
+.. literalinclude:: ../miio/integrations/roborock/vacuum/simulated_roborock.yaml
    :language: yaml
 
 
diff --git a/miio/__init__.py b/miio/__init__.py
index 8789776d8..2c4952cfc 100644
--- a/miio/__init__.py
+++ b/miio/__init__.py
@@ -16,84 +16,68 @@
 
 # isort: on
 
-# Integration imports
-from miio.airconditioner_miot import AirConditionerMiot
-from miio.airconditioningcompanion import (
-    AirConditioningCompanion,
-    AirConditioningCompanionV3,
-)
-from miio.airconditioningcompanionMCN import AirConditioningCompanionMcn02
-from miio.airdehumidifier import AirDehumidifier
-from miio.airqualitymonitor import AirQualityMonitor
-from miio.airqualitymonitor_miot import AirQualityMonitorCGDN1
-from miio.aqaracamera import AqaraCamera
-from miio.chuangmi_camera import ChuangmiCamera
-from miio.chuangmi_ir import ChuangmiIr
-from miio.chuangmi_plug import ChuangmiPlug
 from miio.cloud import CloudInterface
-from miio.cooker import Cooker
-from miio.curtain_youpin import CurtainMiot
 from miio.devicefactory import DeviceFactory
-from miio.gateway import Gateway
-from miio.heater import Heater
-from miio.heater_miot import HeaterMiot
-from miio.huizuo import Huizuo, HuizuoLampFan, HuizuoLampHeater, HuizuoLampScene
-from miio.integrations.airpurifier import (
-    AirDogX3,
-    AirFresh,
-    AirFreshA1,
-    AirFreshT2017,
-    AirPurifier,
-    AirPurifierMiot,
-)
-from miio.integrations.fan import Fan, Fan1C, FanLeshow, FanMiot, FanP5, FanZA5
+from miio.integrations.airdog.airpurifier import AirDogX3
+from miio.integrations.cgllc.airmonitor import AirQualityMonitor, AirQualityMonitorCGDN1
+from miio.integrations.chuangmi.camera import ChuangmiCamera
+from miio.integrations.chuangmi.plug import ChuangmiPlug
+from miio.integrations.chuangmi.remote import ChuangmiIr
+from miio.integrations.chunmi.cooker import Cooker
+from miio.integrations.deerma.humidifier import AirHumidifierJsqs, AirHumidifierMjjsq
+from miio.integrations.dmaker.airfresh import AirFreshA1, AirFreshT2017
+from miio.integrations.dmaker.fan import Fan1C, FanMiot, FanP5
+from miio.integrations.dreame.vacuum import DreameVacuum
 from miio.integrations.genericmiot import GenericMiot
-from miio.integrations.humidifier import (
-    AirHumidifier,
-    AirHumidifierJsq,
-    AirHumidifierJsqs,
-    AirHumidifierMiot,
-    AirHumidifierMjjsq,
+from miio.integrations.huayi.light import (
+    Huizuo,
+    HuizuoLampFan,
+    HuizuoLampHeater,
+    HuizuoLampScene,
 )
-from miio.integrations.light import (
+from miio.integrations.ijai.vacuum import Pro2Vacuum
+from miio.integrations.ksmb.walkingpad import Walkingpad
+from miio.integrations.leshow.fan import FanLeshow
+from miio.integrations.lumi.acpartner import (
+    AirConditioningCompanion,
+    AirConditioningCompanionMcn02,
+    AirConditioningCompanionV3,
+)
+from miio.integrations.lumi.camera.aqaracamera import AqaraCamera
+from miio.integrations.lumi.curtain import CurtainMiot
+from miio.integrations.lumi.gateway import Gateway
+from miio.integrations.mijia.vacuum import G1Vacuum
+from miio.integrations.mmgg.petwaterdispenser import PetWaterDispenser
+from miio.integrations.nwt.dehumidifier import AirDehumidifier
+from miio.integrations.philips.light import (
     Ceil,
     PhilipsBulb,
     PhilipsEyecare,
     PhilipsMoonlight,
     PhilipsRwread,
     PhilipsWhiteBulb,
-    Yeelight,
-)
-from miio.integrations.petwaterdispenser import PetWaterDispenser
-from miio.integrations.vacuum import (
-    DreameVacuum,
-    G1Vacuum,
-    Pro2Vacuum,
-    RoborockVacuum,
-    RoidmiVacuumMiot,
-    ViomiVacuum,
-)
-from miio.integrations.vacuum.roborock.vacuumcontainers import (
-    CleaningDetails,
-    CleaningSummary,
-    ConsumableStatus,
-    DNDStatus,
-    Timer,
-    VacuumStatus,
 )
-from miio.integrations.viomidishwasher import ViomiDishwasher
-from miio.powerstrip import PowerStrip
+from miio.integrations.pwzn.relay import PwznRelay
+from miio.integrations.roborock.vacuum import RoborockVacuum
+from miio.integrations.roidmi.vacuum import RoidmiVacuumMiot
+from miio.integrations.scishare.coffee import ScishareCoffee
+from miio.integrations.shuii.humidifier import AirHumidifierJsq
+from miio.integrations.tinymu.toiletlid import Toiletlid
+from miio.integrations.viomi.viomi import ViomiVacuum
+from miio.integrations.viomi.viomidishwasher import ViomiDishwasher
+from miio.integrations.xiaomi.aircondition.airconditioner_miot import AirConditionerMiot
+from miio.integrations.xiaomi.repeater.wifirepeater import WifiRepeater
+from miio.integrations.xiaomi.wifispeaker.wifispeaker import WifiSpeaker
+from miio.integrations.yeelight.dual_switch import YeelightDualControlModule
+from miio.integrations.yeelight.light import Yeelight
+from miio.integrations.yunmi.waterpurifier import WaterPurifier, WaterPurifierYunmi
+from miio.integrations.zhimi.airpurifier import AirFresh, AirPurifier, AirPurifierMiot
+from miio.integrations.zhimi.fan import Fan, FanZA5
+from miio.integrations.zhimi.heater import Heater, HeaterMiot
+from miio.integrations.zhimi.humidifier import AirHumidifier, AirHumidifierMiot
+from miio.integrations.zimi.powerstrip import PowerStrip
 from miio.protocol import Message, Utils
 from miio.push_server import EventInfo, PushServer
-from miio.pwzn_relay import PwznRelay
-from miio.scishare_coffeemaker import ScishareCoffee
-from miio.toiletlid import Toiletlid
-from miio.walkingpad import Walkingpad
-from miio.waterpurifier import WaterPurifier
-from miio.waterpurifier_yunmi import WaterPurifierYunmi
-from miio.wifirepeater import WifiRepeater
-from miio.wifispeaker import WifiSpeaker
-from miio.yeelight_dual_switch import YeelightDualControlModule
 
 from miio.discovery import Discovery
 
diff --git a/miio/integrations/airpurifier/airdog/tests/__init__.py b/miio/integrations/airdog/__init__.py
similarity index 100%
rename from miio/integrations/airpurifier/airdog/tests/__init__.py
rename to miio/integrations/airdog/__init__.py
diff --git a/miio/integrations/airpurifier/airdog/__init__.py b/miio/integrations/airdog/airpurifier/__init__.py
similarity index 100%
rename from miio/integrations/airpurifier/airdog/__init__.py
rename to miio/integrations/airdog/airpurifier/__init__.py
diff --git a/miio/integrations/airpurifier/airdog/airpurifier_airdog.py b/miio/integrations/airdog/airpurifier/airpurifier_airdog.py
similarity index 100%
rename from miio/integrations/airpurifier/airdog/airpurifier_airdog.py
rename to miio/integrations/airdog/airpurifier/airpurifier_airdog.py
diff --git a/miio/integrations/airpurifier/__init__.py b/miio/integrations/airpurifier/__init__.py
deleted file mode 100644
index fd5aad3f1..000000000
--- a/miio/integrations/airpurifier/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# flake8: noqa
-from .airdog import *
-from .dmaker import *
-from .zhimi import *
diff --git a/miio/integrations/airpurifier/zhimi/tests/__init__.py b/miio/integrations/cgllc/__init__.py
similarity index 100%
rename from miio/integrations/airpurifier/zhimi/tests/__init__.py
rename to miio/integrations/cgllc/__init__.py
diff --git a/miio/integrations/cgllc/airmonitor/__init__.py b/miio/integrations/cgllc/airmonitor/__init__.py
new file mode 100644
index 000000000..37eafd250
--- /dev/null
+++ b/miio/integrations/cgllc/airmonitor/__init__.py
@@ -0,0 +1,4 @@
+from .airqualitymonitor import AirQualityMonitor
+from .airqualitymonitor_miot import AirQualityMonitorCGDN1
+
+__all__ = ["AirQualityMonitor", "AirQualityMonitorCGDN1"]
diff --git a/miio/airqualitymonitor.py b/miio/integrations/cgllc/airmonitor/airqualitymonitor.py
similarity index 98%
rename from miio/airqualitymonitor.py
rename to miio/integrations/cgllc/airmonitor/airqualitymonitor.py
index f44ea0ec9..a49456229 100644
--- a/miio/airqualitymonitor.py
+++ b/miio/integrations/cgllc/airmonitor/airqualitymonitor.py
@@ -4,11 +4,12 @@
 
 import click
 
-from .click_common import command, format_output
-from .device import Device, DeviceStatus
+from miio.click_common import command, format_output
+from miio.device import Device, DeviceStatus
 
 _LOGGER = logging.getLogger(__name__)
 
+# TODO: move zhimi into its own place
 MODEL_AIRQUALITYMONITOR_V1 = "zhimi.airmonitor.v1"
 MODEL_AIRQUALITYMONITOR_B1 = "cgllc.airmonitor.b1"
 MODEL_AIRQUALITYMONITOR_S1 = "cgllc.airmonitor.s1"
diff --git a/miio/airqualitymonitor_miot.py b/miio/integrations/cgllc/airmonitor/airqualitymonitor_miot.py
similarity index 98%
rename from miio/airqualitymonitor_miot.py
rename to miio/integrations/cgllc/airmonitor/airqualitymonitor_miot.py
index ce8f5cbac..a405f9a46 100644
--- a/miio/airqualitymonitor_miot.py
+++ b/miio/integrations/cgllc/airmonitor/airqualitymonitor_miot.py
@@ -3,8 +3,8 @@
 
 import click
 
-from .click_common import command, format_output
-from .miot_device import DeviceStatus, MiotDevice
+from miio.click_common import command, format_output
+from miio.miot_device import DeviceStatus, MiotDevice
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/integrations/fan/leshow/tests/__init__.py b/miio/integrations/chuangmi/__init__.py
similarity index 100%
rename from miio/integrations/fan/leshow/tests/__init__.py
rename to miio/integrations/chuangmi/__init__.py
diff --git a/miio/integrations/chuangmi/camera/__init__.py b/miio/integrations/chuangmi/camera/__init__.py
new file mode 100644
index 000000000..bd6917305
--- /dev/null
+++ b/miio/integrations/chuangmi/camera/__init__.py
@@ -0,0 +1,3 @@
+from .chuangmi_camera import ChuangmiCamera
+
+__all__ = ["ChuangmiCamera"]
diff --git a/miio/chuangmi_camera.py b/miio/integrations/chuangmi/camera/chuangmi_camera.py
similarity index 99%
rename from miio/chuangmi_camera.py
rename to miio/integrations/chuangmi/camera/chuangmi_camera.py
index 78cf2b19a..19cb69493 100644
--- a/miio/chuangmi_camera.py
+++ b/miio/integrations/chuangmi/camera/chuangmi_camera.py
@@ -9,8 +9,8 @@
 
 import click
 
-from .click_common import EnumType, command, format_output
-from .device import Device, DeviceStatus
+from miio.click_common import EnumType, command, format_output
+from miio.device import Device, DeviceStatus
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/integrations/chuangmi/plug/__init__.py b/miio/integrations/chuangmi/plug/__init__.py
new file mode 100644
index 000000000..9171efc01
--- /dev/null
+++ b/miio/integrations/chuangmi/plug/__init__.py
@@ -0,0 +1,3 @@
+from .chuangmi_plug import ChuangmiPlug
+
+__all__ = ["ChuangmiPlug"]
diff --git a/miio/chuangmi_plug.py b/miio/integrations/chuangmi/plug/chuangmi_plug.py
similarity index 97%
rename from miio/chuangmi_plug.py
rename to miio/integrations/chuangmi/plug/chuangmi_plug.py
index 90d7b9a12..1b6b07db7 100644
--- a/miio/chuangmi_plug.py
+++ b/miio/integrations/chuangmi/plug/chuangmi_plug.py
@@ -4,10 +4,9 @@
 
 import click
 
-from .click_common import command, format_output
-from .device import Device, DeviceStatus
-from .exceptions import DeviceException
-from .utils import deprecated
+from miio import Device, DeviceException, DeviceStatus
+from miio.click_common import command, format_output
+from miio.utils import deprecated
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/integrations/chuangmi/remote/__init__.py b/miio/integrations/chuangmi/remote/__init__.py
new file mode 100644
index 000000000..177a89bce
--- /dev/null
+++ b/miio/integrations/chuangmi/remote/__init__.py
@@ -0,0 +1,3 @@
+from .chuangmi_ir import ChuangmiIr
+
+__all__ = ["ChuangmiIr"]
diff --git a/miio/chuangmi_ir.py b/miio/integrations/chuangmi/remote/chuangmi_ir.py
similarity index 98%
rename from miio/chuangmi_ir.py
rename to miio/integrations/chuangmi/remote/chuangmi_ir.py
index 8915b965f..fcd490b75 100644
--- a/miio/chuangmi_ir.py
+++ b/miio/integrations/chuangmi/remote/chuangmi_ir.py
@@ -19,8 +19,8 @@
     this,
 )
 
-from .click_common import command, format_output
-from .device import Device
+from miio.click_common import command, format_output
+from miio.device import Device
 
 
 class ChuangmiIr(Device):
diff --git a/miio/integrations/humidifier/deerma/tests/__init__.py b/miio/integrations/chunmi/__init__.py
similarity index 100%
rename from miio/integrations/humidifier/deerma/tests/__init__.py
rename to miio/integrations/chunmi/__init__.py
diff --git a/miio/integrations/chunmi/cooker/__init__.py b/miio/integrations/chunmi/cooker/__init__.py
new file mode 100644
index 000000000..68556f582
--- /dev/null
+++ b/miio/integrations/chunmi/cooker/__init__.py
@@ -0,0 +1,3 @@
+from .cooker import Cooker
+
+__all__ = ["Cooker"]
diff --git a/miio/cooker.py b/miio/integrations/chunmi/cooker/cooker.py
similarity index 99%
rename from miio/cooker.py
rename to miio/integrations/chunmi/cooker/cooker.py
index 63df7601c..fecc09742 100644
--- a/miio/cooker.py
+++ b/miio/integrations/chunmi/cooker/cooker.py
@@ -7,8 +7,8 @@
 
 import click
 
-from .click_common import command, format_output
-from .device import Device, DeviceStatus
+from miio.click_common import command, format_output
+from miio.device import Device, DeviceStatus
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/integrations/humidifier/shuii/tests/__init__.py b/miio/integrations/deerma/__init__.py
similarity index 100%
rename from miio/integrations/humidifier/shuii/tests/__init__.py
rename to miio/integrations/deerma/__init__.py
diff --git a/miio/integrations/humidifier/deerma/__init__.py b/miio/integrations/deerma/humidifier/__init__.py
similarity index 100%
rename from miio/integrations/humidifier/deerma/__init__.py
rename to miio/integrations/deerma/humidifier/__init__.py
diff --git a/miio/integrations/humidifier/deerma/airhumidifier_jsqs.py b/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py
similarity index 100%
rename from miio/integrations/humidifier/deerma/airhumidifier_jsqs.py
rename to miio/integrations/deerma/humidifier/airhumidifier_jsqs.py
diff --git a/miio/integrations/humidifier/deerma/airhumidifier_mjjsq.py b/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py
similarity index 100%
rename from miio/integrations/humidifier/deerma/airhumidifier_mjjsq.py
rename to miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py
diff --git a/miio/integrations/light/philips/tests/__init__.py b/miio/integrations/dmaker/__init__.py
similarity index 100%
rename from miio/integrations/light/philips/tests/__init__.py
rename to miio/integrations/dmaker/__init__.py
diff --git a/miio/integrations/airpurifier/dmaker/__init__.py b/miio/integrations/dmaker/airfresh/__init__.py
similarity index 100%
rename from miio/integrations/airpurifier/dmaker/__init__.py
rename to miio/integrations/dmaker/airfresh/__init__.py
diff --git a/miio/integrations/airpurifier/dmaker/airfresh_t2017.py b/miio/integrations/dmaker/airfresh/airfresh_t2017.py
similarity index 100%
rename from miio/integrations/airpurifier/dmaker/airfresh_t2017.py
rename to miio/integrations/dmaker/airfresh/airfresh_t2017.py
diff --git a/miio/integrations/fan/dmaker/__init__.py b/miio/integrations/dmaker/fan/__init__.py
similarity index 100%
rename from miio/integrations/fan/dmaker/__init__.py
rename to miio/integrations/dmaker/fan/__init__.py
diff --git a/miio/integrations/fan/dmaker/fan.py b/miio/integrations/dmaker/fan/fan.py
similarity index 100%
rename from miio/integrations/fan/dmaker/fan.py
rename to miio/integrations/dmaker/fan/fan.py
diff --git a/miio/integrations/fan/dmaker/fan_miot.py b/miio/integrations/dmaker/fan/fan_miot.py
similarity index 100%
rename from miio/integrations/fan/dmaker/fan_miot.py
rename to miio/integrations/dmaker/fan/fan_miot.py
diff --git a/miio/integrations/petwaterdispenser/tests/__init__.py b/miio/integrations/dreame/__init__.py
similarity index 100%
rename from miio/integrations/petwaterdispenser/tests/__init__.py
rename to miio/integrations/dreame/__init__.py
diff --git a/miio/integrations/vacuum/dreame/__init__.py b/miio/integrations/dreame/vacuum/__init__.py
similarity index 100%
rename from miio/integrations/vacuum/dreame/__init__.py
rename to miio/integrations/dreame/vacuum/__init__.py
diff --git a/miio/integrations/vacuum/dreame/dreamevacuum_miot.py b/miio/integrations/dreame/vacuum/dreamevacuum_miot.py
similarity index 100%
rename from miio/integrations/vacuum/dreame/dreamevacuum_miot.py
rename to miio/integrations/dreame/vacuum/dreamevacuum_miot.py
diff --git a/miio/integrations/fan/__init__.py b/miio/integrations/fan/__init__.py
deleted file mode 100644
index f34286872..000000000
--- a/miio/integrations/fan/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# flake8: noqa
-from .dmaker import *
-from .leshow import *
-from .zhimi import *
diff --git a/miio/integrations/vacuum/roborock/tests/__init__.py b/miio/integrations/huayi/__init__.py
similarity index 100%
rename from miio/integrations/vacuum/roborock/tests/__init__.py
rename to miio/integrations/huayi/__init__.py
diff --git a/miio/integrations/huayi/light/__init__.py b/miio/integrations/huayi/light/__init__.py
new file mode 100644
index 000000000..d4c9d3c0a
--- /dev/null
+++ b/miio/integrations/huayi/light/__init__.py
@@ -0,0 +1,3 @@
+from .huizuo import Huizuo, HuizuoLampFan, HuizuoLampHeater, HuizuoLampScene
+
+__all__ = ["Huizuo", "HuizuoLampFan", "HuizuoLampHeater", "HuizuoLampScene"]
diff --git a/miio/huizuo.py b/miio/integrations/huayi/light/huizuo.py
similarity index 99%
rename from miio/huizuo.py
rename to miio/integrations/huayi/light/huizuo.py
index 98eccf544..ce234c0d5 100644
--- a/miio/huizuo.py
+++ b/miio/integrations/huayi/light/huizuo.py
@@ -9,9 +9,8 @@
 
 import click
 
-from .click_common import command, format_output
-from .exceptions import UnsupportedFeatureException
-from .miot_device import DeviceStatus, MiotDevice
+from miio import DeviceStatus, MiotDevice, UnsupportedFeatureException
+from miio.click_common import command, format_output
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/integrations/humidifier/__init__.py b/miio/integrations/humidifier/__init__.py
deleted file mode 100644
index 3320258f1..000000000
--- a/miio/integrations/humidifier/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# flake8: noqa
-from .deerma import *
-from .shuii import *
-from .zhimi import *
diff --git a/miio/integrations/vacuum/roidmi/tests/__init__.py b/miio/integrations/ijai/__init__.py
similarity index 100%
rename from miio/integrations/vacuum/roidmi/tests/__init__.py
rename to miio/integrations/ijai/__init__.py
diff --git a/miio/integrations/ijai/vacuum/__init__.py b/miio/integrations/ijai/vacuum/__init__.py
new file mode 100644
index 000000000..af64112c8
--- /dev/null
+++ b/miio/integrations/ijai/vacuum/__init__.py
@@ -0,0 +1,3 @@
+from .pro2vacuum import Pro2Vacuum
+
+__all__ = ["Pro2Vacuum"]
diff --git a/miio/integrations/vacuum/mijia/pro2vacuum.py b/miio/integrations/ijai/vacuum/pro2vacuum.py
similarity index 100%
rename from miio/integrations/vacuum/mijia/pro2vacuum.py
rename to miio/integrations/ijai/vacuum/pro2vacuum.py
diff --git a/miio/integrations/ksmb/__init__.py b/miio/integrations/ksmb/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/ksmb/walkingpad/__init__.py b/miio/integrations/ksmb/walkingpad/__init__.py
new file mode 100644
index 000000000..881593622
--- /dev/null
+++ b/miio/integrations/ksmb/walkingpad/__init__.py
@@ -0,0 +1,3 @@
+from .walkingpad import Walkingpad
+
+__all__ = ["Walkingpad"]
diff --git a/miio/walkingpad.py b/miio/integrations/ksmb/walkingpad/walkingpad.py
similarity index 98%
rename from miio/walkingpad.py
rename to miio/integrations/ksmb/walkingpad/walkingpad.py
index 094d6fbf4..bc009cc95 100644
--- a/miio/walkingpad.py
+++ b/miio/integrations/ksmb/walkingpad/walkingpad.py
@@ -5,9 +5,8 @@
 
 import click
 
-from .click_common import EnumType, command, format_output
-from .device import Device, DeviceStatus
-from .exceptions import DeviceException
+from miio import Device, DeviceException, DeviceStatus
+from miio.click_common import EnumType, command, format_output
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/integrations/leshow/__init__.py b/miio/integrations/leshow/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/fan/leshow/__init__.py b/miio/integrations/leshow/fan/__init__.py
similarity index 100%
rename from miio/integrations/fan/leshow/__init__.py
rename to miio/integrations/leshow/fan/__init__.py
diff --git a/miio/integrations/fan/leshow/fan_leshow.py b/miio/integrations/leshow/fan/fan_leshow.py
similarity index 100%
rename from miio/integrations/fan/leshow/fan_leshow.py
rename to miio/integrations/leshow/fan/fan_leshow.py
diff --git a/miio/integrations/light/__init__.py b/miio/integrations/light/__init__.py
deleted file mode 100644
index 9502d05a0..000000000
--- a/miio/integrations/light/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# flake8: noqa
-from .philips import *
-from .yeelight import *
diff --git a/miio/integrations/lumi/__init__.py b/miio/integrations/lumi/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/lumi/acpartner/__init__.py b/miio/integrations/lumi/acpartner/__init__.py
new file mode 100644
index 000000000..a136463f8
--- /dev/null
+++ b/miio/integrations/lumi/acpartner/__init__.py
@@ -0,0 +1,11 @@
+from .airconditioningcompanion import (
+    AirConditioningCompanion,
+    AirConditioningCompanionV3,
+)
+from .airconditioningcompanionMCN import AirConditioningCompanionMcn02
+
+__all__ = [
+    "AirConditioningCompanion",
+    "AirConditioningCompanionV3",
+    "AirConditioningCompanionMcn02",
+]
diff --git a/miio/airconditioningcompanion.py b/miio/integrations/lumi/acpartner/airconditioningcompanion.py
similarity index 99%
rename from miio/airconditioningcompanion.py
rename to miio/integrations/lumi/acpartner/airconditioningcompanion.py
index 563f94920..4824dca95 100644
--- a/miio/airconditioningcompanion.py
+++ b/miio/integrations/lumi/acpartner/airconditioningcompanion.py
@@ -4,8 +4,8 @@
 
 import click
 
-from .click_common import EnumType, command, format_output
-from .device import Device, DeviceStatus
+from miio import Device, DeviceStatus
+from miio.click_common import EnumType, command, format_output
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/airconditioningcompanionMCN.py b/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py
similarity index 97%
rename from miio/airconditioningcompanionMCN.py
rename to miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py
index bd6e81098..d463502b2 100644
--- a/miio/airconditioningcompanionMCN.py
+++ b/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py
@@ -3,8 +3,8 @@
 import random
 from typing import Any, Optional
 
-from .click_common import command, format_output
-from .device import Device, DeviceStatus
+from miio import Device, DeviceStatus
+from miio.click_common import command, format_output
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/integrations/lumi/camera/__init__.py b/miio/integrations/lumi/camera/__init__.py
new file mode 100644
index 000000000..f58d0eb96
--- /dev/null
+++ b/miio/integrations/lumi/camera/__init__.py
@@ -0,0 +1,3 @@
+from .aqaracamera import AqaraCamera
+
+__all__ = ["AqaraCamera"]
diff --git a/miio/aqaracamera.py b/miio/integrations/lumi/camera/aqaracamera.py
similarity index 98%
rename from miio/aqaracamera.py
rename to miio/integrations/lumi/camera/aqaracamera.py
index 28b62dce3..ee2755d95 100644
--- a/miio/aqaracamera.py
+++ b/miio/integrations/lumi/camera/aqaracamera.py
@@ -14,8 +14,8 @@
 import attr
 import click
 
-from .click_common import command, format_output
-from .device import Device, DeviceStatus
+from miio import Device, DeviceStatus
+from miio.click_common import command, format_output
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/integrations/lumi/curtain/__init__.py b/miio/integrations/lumi/curtain/__init__.py
new file mode 100644
index 000000000..62f9baf3d
--- /dev/null
+++ b/miio/integrations/lumi/curtain/__init__.py
@@ -0,0 +1,3 @@
+from .curtain_youpin import CurtainMiot
+
+__all__ = ["CurtainMiot"]
diff --git a/miio/curtain_youpin.py b/miio/integrations/lumi/curtain/curtain_youpin.py
similarity index 98%
rename from miio/curtain_youpin.py
rename to miio/integrations/lumi/curtain/curtain_youpin.py
index 033169364..b0373f4c4 100644
--- a/miio/curtain_youpin.py
+++ b/miio/integrations/lumi/curtain/curtain_youpin.py
@@ -4,8 +4,8 @@
 
 import click
 
-from .click_common import EnumType, command, format_output
-from .miot_device import DeviceStatus, MiotDevice
+from miio import DeviceStatus, MiotDevice
+from miio.click_common import EnumType, command, format_output
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/gateway/__init__.py b/miio/integrations/lumi/gateway/__init__.py
similarity index 100%
rename from miio/gateway/__init__.py
rename to miio/integrations/lumi/gateway/__init__.py
diff --git a/miio/gateway/alarm.py b/miio/integrations/lumi/gateway/alarm.py
similarity index 97%
rename from miio/gateway/alarm.py
rename to miio/integrations/lumi/gateway/alarm.py
index e641ef4c8..d681442fe 100644
--- a/miio/gateway/alarm.py
+++ b/miio/integrations/lumi/gateway/alarm.py
@@ -3,8 +3,9 @@
 import logging
 from datetime import datetime
 
-from ..exceptions import DeviceException
-from ..push_server import EventInfo
+from miio import DeviceException
+from miio.push_server import EventInfo
+
 from .gatewaydevice import GatewayDevice
 
 _LOGGER = logging.getLogger(__name__)
diff --git a/miio/gateway/devices/__init__.py b/miio/integrations/lumi/gateway/devices/__init__.py
similarity index 100%
rename from miio/gateway/devices/__init__.py
rename to miio/integrations/lumi/gateway/devices/__init__.py
diff --git a/miio/gateway/devices/light.py b/miio/integrations/lumi/gateway/devices/light.py
similarity index 95%
rename from miio/gateway/devices/light.py
rename to miio/integrations/lumi/gateway/devices/light.py
index 3604470e6..2e7f0cd45 100644
--- a/miio/gateway/devices/light.py
+++ b/miio/integrations/lumi/gateway/devices/light.py
@@ -2,7 +2,8 @@
 
 import click
 
-from ...click_common import command
+from miio.click_common import command
+
 from .subdevice import SubDevice
 
 
diff --git a/miio/gateway/devices/sensor.py b/miio/integrations/lumi/gateway/devices/sensor.py
similarity index 91%
rename from miio/gateway/devices/sensor.py
rename to miio/integrations/lumi/gateway/devices/sensor.py
index cdb61fa4f..c4b7e971c 100644
--- a/miio/gateway/devices/sensor.py
+++ b/miio/integrations/lumi/gateway/devices/sensor.py
@@ -2,7 +2,8 @@
 
 import click
 
-from ...click_common import command
+from miio.click_common import command
+
 from .subdevice import SubDevice
 
 
diff --git a/miio/gateway/devices/subdevice.py b/miio/integrations/lumi/gateway/devices/subdevice.py
similarity index 98%
rename from miio/gateway/devices/subdevice.py
rename to miio/integrations/lumi/gateway/devices/subdevice.py
index 09369ae17..590d12247 100644
--- a/miio/gateway/devices/subdevice.py
+++ b/miio/integrations/lumi/gateway/devices/subdevice.py
@@ -6,9 +6,10 @@
 import attr
 import click
 
-from ...click_common import command
-from ...exceptions import DeviceException
-from ...push_server import EventInfo
+from miio import DeviceException
+from miio.click_common import command
+from miio.push_server import EventInfo
+
 from ..gateway import GATEWAY_MODEL_EU, GATEWAY_MODEL_ZIG3, GatewayCallback
 
 _LOGGER = logging.getLogger(__name__)
diff --git a/miio/gateway/devices/subdevices.yaml b/miio/integrations/lumi/gateway/devices/subdevices.yaml
similarity index 100%
rename from miio/gateway/devices/subdevices.yaml
rename to miio/integrations/lumi/gateway/devices/subdevices.yaml
diff --git a/miio/gateway/devices/switch.py b/miio/integrations/lumi/gateway/devices/switch.py
similarity index 96%
rename from miio/gateway/devices/switch.py
rename to miio/integrations/lumi/gateway/devices/switch.py
index e572303d5..9a7e555ff 100644
--- a/miio/gateway/devices/switch.py
+++ b/miio/integrations/lumi/gateway/devices/switch.py
@@ -4,7 +4,8 @@
 
 import click
 
-from ...click_common import command
+from miio.click_common import command
+
 from .subdevice import SubDevice
 
 
diff --git a/miio/gateway/gateway.py b/miio/integrations/lumi/gateway/gateway.py
similarity index 99%
rename from miio/gateway/gateway.py
rename to miio/integrations/lumi/gateway/gateway.py
index 385fe563a..31eaa49bf 100644
--- a/miio/gateway/gateway.py
+++ b/miio/integrations/lumi/gateway/gateway.py
@@ -8,9 +8,9 @@
 import click
 import yaml
 
-from ..click_common import command
-from ..device import Device
-from ..exceptions import DeviceError, DeviceException
+from miio import Device, DeviceError, DeviceException
+from miio.click_common import command
+
 from .alarm import Alarm
 from .light import Light
 from .radio import Radio
diff --git a/miio/gateway/gatewaydevice.py b/miio/integrations/lumi/gateway/gatewaydevice.py
similarity index 94%
rename from miio/gateway/gatewaydevice.py
rename to miio/integrations/lumi/gateway/gatewaydevice.py
index b6e081ca1..d2c271916 100644
--- a/miio/gateway/gatewaydevice.py
+++ b/miio/integrations/lumi/gateway/gatewaydevice.py
@@ -3,7 +3,7 @@
 import logging
 from typing import TYPE_CHECKING, List, Optional
 
-from ..exceptions import DeviceException
+from miio import DeviceException
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/gateway/light.py b/miio/integrations/lumi/gateway/light.py
similarity index 98%
rename from miio/gateway/light.py
rename to miio/integrations/lumi/gateway/light.py
index f800ef9ed..3f39cbd40 100644
--- a/miio/gateway/light.py
+++ b/miio/integrations/lumi/gateway/light.py
@@ -2,7 +2,8 @@
 
 from typing import Tuple
 
-from ..utils import brightness_and_color_to_int, int_to_brightness, int_to_rgb
+from miio.utils import brightness_and_color_to_int, int_to_brightness, int_to_rgb
+
 from .gatewaydevice import GatewayDevice
 
 color_map = {
diff --git a/miio/gateway/radio.py b/miio/integrations/lumi/gateway/radio.py
similarity index 100%
rename from miio/gateway/radio.py
rename to miio/integrations/lumi/gateway/radio.py
diff --git a/miio/gateway/zigbee.py b/miio/integrations/lumi/gateway/zigbee.py
similarity index 100%
rename from miio/gateway/zigbee.py
rename to miio/integrations/lumi/gateway/zigbee.py
diff --git a/miio/integrations/mijia/__init__.py b/miio/integrations/mijia/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/vacuum/mijia/__init__.py b/miio/integrations/mijia/vacuum/__init__.py
similarity index 56%
rename from miio/integrations/vacuum/mijia/__init__.py
rename to miio/integrations/mijia/vacuum/__init__.py
index 8d737a529..2ebcbbdb3 100644
--- a/miio/integrations/vacuum/mijia/__init__.py
+++ b/miio/integrations/mijia/vacuum/__init__.py
@@ -1,3 +1,2 @@
 # flake8: noqa
 from .g1vacuum import G1Vacuum
-from .pro2vacuum import Pro2Vacuum
diff --git a/miio/integrations/vacuum/mijia/g1vacuum.py b/miio/integrations/mijia/vacuum/g1vacuum.py
similarity index 100%
rename from miio/integrations/vacuum/mijia/g1vacuum.py
rename to miio/integrations/mijia/vacuum/g1vacuum.py
diff --git a/miio/integrations/mmgg/__init__.py b/miio/integrations/mmgg/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/petwaterdispenser/__init__.py b/miio/integrations/mmgg/petwaterdispenser/__init__.py
similarity index 100%
rename from miio/integrations/petwaterdispenser/__init__.py
rename to miio/integrations/mmgg/petwaterdispenser/__init__.py
diff --git a/miio/integrations/petwaterdispenser/device.py b/miio/integrations/mmgg/petwaterdispenser/device.py
similarity index 100%
rename from miio/integrations/petwaterdispenser/device.py
rename to miio/integrations/mmgg/petwaterdispenser/device.py
diff --git a/miio/integrations/petwaterdispenser/status.py b/miio/integrations/mmgg/petwaterdispenser/status.py
similarity index 100%
rename from miio/integrations/petwaterdispenser/status.py
rename to miio/integrations/mmgg/petwaterdispenser/status.py
diff --git a/miio/integrations/nwt/__init__.py b/miio/integrations/nwt/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/nwt/dehumidifier/__init__.py b/miio/integrations/nwt/dehumidifier/__init__.py
new file mode 100644
index 000000000..f21a4d67e
--- /dev/null
+++ b/miio/integrations/nwt/dehumidifier/__init__.py
@@ -0,0 +1,3 @@
+from .airdehumidifier import AirDehumidifier
+
+__all__ = ["AirDehumidifier"]
diff --git a/miio/airdehumidifier.py b/miio/integrations/nwt/dehumidifier/airdehumidifier.py
similarity index 97%
rename from miio/airdehumidifier.py
rename to miio/integrations/nwt/dehumidifier/airdehumidifier.py
index 15fd1b620..5a8cafcf1 100644
--- a/miio/airdehumidifier.py
+++ b/miio/integrations/nwt/dehumidifier/airdehumidifier.py
@@ -5,9 +5,8 @@
 
 import click
 
-from .click_common import EnumType, command, format_output
-from .device import Device, DeviceInfo, DeviceStatus
-from .exceptions import DeviceError, DeviceException
+from miio import Device, DeviceError, DeviceException, DeviceInfo, DeviceStatus
+from miio.click_common import EnumType, command, format_output
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/integrations/philips/__init__.py b/miio/integrations/philips/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/light/philips/__init__.py b/miio/integrations/philips/light/__init__.py
similarity index 100%
rename from miio/integrations/light/philips/__init__.py
rename to miio/integrations/philips/light/__init__.py
diff --git a/miio/integrations/light/philips/ceil.py b/miio/integrations/philips/light/ceil.py
similarity index 100%
rename from miio/integrations/light/philips/ceil.py
rename to miio/integrations/philips/light/ceil.py
diff --git a/miio/integrations/light/philips/philips_bulb.py b/miio/integrations/philips/light/philips_bulb.py
similarity index 100%
rename from miio/integrations/light/philips/philips_bulb.py
rename to miio/integrations/philips/light/philips_bulb.py
diff --git a/miio/integrations/light/philips/philips_eyecare.py b/miio/integrations/philips/light/philips_eyecare.py
similarity index 100%
rename from miio/integrations/light/philips/philips_eyecare.py
rename to miio/integrations/philips/light/philips_eyecare.py
diff --git a/miio/integrations/light/philips/philips_moonlight.py b/miio/integrations/philips/light/philips_moonlight.py
similarity index 100%
rename from miio/integrations/light/philips/philips_moonlight.py
rename to miio/integrations/philips/light/philips_moonlight.py
diff --git a/miio/integrations/light/philips/philips_rwread.py b/miio/integrations/philips/light/philips_rwread.py
similarity index 100%
rename from miio/integrations/light/philips/philips_rwread.py
rename to miio/integrations/philips/light/philips_rwread.py
diff --git a/miio/integrations/pwzn/__init__.py b/miio/integrations/pwzn/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/pwzn/relay/__init__.py b/miio/integrations/pwzn/relay/__init__.py
new file mode 100644
index 000000000..a44ca5804
--- /dev/null
+++ b/miio/integrations/pwzn/relay/__init__.py
@@ -0,0 +1,3 @@
+from .pwzn_relay import PwznRelay
+
+__all__ = ["PwznRelay"]
diff --git a/miio/pwzn_relay.py b/miio/integrations/pwzn/relay/pwzn_relay.py
similarity index 97%
rename from miio/pwzn_relay.py
rename to miio/integrations/pwzn/relay/pwzn_relay.py
index 95f146024..0d937bc7e 100644
--- a/miio/pwzn_relay.py
+++ b/miio/integrations/pwzn/relay/pwzn_relay.py
@@ -4,8 +4,8 @@
 
 import click
 
-from .click_common import command, format_output
-from .device import Device, DeviceStatus
+from miio import Device, DeviceStatus
+from miio.click_common import command, format_output
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/integrations/roborock/__init__.py b/miio/integrations/roborock/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/vacuum/roborock/__init__.py b/miio/integrations/roborock/vacuum/__init__.py
similarity index 100%
rename from miio/integrations/vacuum/roborock/__init__.py
rename to miio/integrations/roborock/vacuum/__init__.py
diff --git a/miio/integrations/vacuum/roborock/simulated_roborock.yaml b/miio/integrations/roborock/vacuum/simulated_roborock.yaml
similarity index 100%
rename from miio/integrations/vacuum/roborock/simulated_roborock.yaml
rename to miio/integrations/roborock/vacuum/simulated_roborock.yaml
diff --git a/miio/integrations/vacuum/roborock/vacuum.py b/miio/integrations/roborock/vacuum/vacuum.py
similarity index 100%
rename from miio/integrations/vacuum/roborock/vacuum.py
rename to miio/integrations/roborock/vacuum/vacuum.py
diff --git a/miio/integrations/vacuum/roborock/vacuum_cli.py b/miio/integrations/roborock/vacuum/vacuum_cli.py
similarity index 100%
rename from miio/integrations/vacuum/roborock/vacuum_cli.py
rename to miio/integrations/roborock/vacuum/vacuum_cli.py
diff --git a/miio/integrations/vacuum/roborock/vacuum_enums.py b/miio/integrations/roborock/vacuum/vacuum_enums.py
similarity index 100%
rename from miio/integrations/vacuum/roborock/vacuum_enums.py
rename to miio/integrations/roborock/vacuum/vacuum_enums.py
diff --git a/miio/integrations/vacuum/roborock/vacuum_tui.py b/miio/integrations/roborock/vacuum/vacuum_tui.py
similarity index 100%
rename from miio/integrations/vacuum/roborock/vacuum_tui.py
rename to miio/integrations/roborock/vacuum/vacuum_tui.py
diff --git a/miio/integrations/vacuum/roborock/vacuumcontainers.py b/miio/integrations/roborock/vacuum/vacuumcontainers.py
similarity index 100%
rename from miio/integrations/vacuum/roborock/vacuumcontainers.py
rename to miio/integrations/roborock/vacuum/vacuumcontainers.py
diff --git a/miio/integrations/roidmi/__init__.py b/miio/integrations/roidmi/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/vacuum/roidmi/__init__.py b/miio/integrations/roidmi/vacuum/__init__.py
similarity index 100%
rename from miio/integrations/vacuum/roidmi/__init__.py
rename to miio/integrations/roidmi/vacuum/__init__.py
diff --git a/miio/integrations/vacuum/roidmi/roidmivacuum_miot.py b/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py
similarity index 99%
rename from miio/integrations/vacuum/roidmi/roidmivacuum_miot.py
rename to miio/integrations/roidmi/vacuum/roidmivacuum_miot.py
index 95e1ae4d2..71df21f75 100644
--- a/miio/integrations/vacuum/roidmi/roidmivacuum_miot.py
+++ b/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py
@@ -10,7 +10,9 @@
 import click
 
 from miio.click_common import EnumType, command
-from miio.integrations.vacuum.roborock.vacuumcontainers import DNDStatus
+from miio.integrations.roborock.vacuum.vacuumcontainers import (  # TODO: remove roborock import
+    DNDStatus,
+)
 from miio.interfaces import FanspeedPresets, VacuumInterface
 from miio.miot_device import DeviceStatus, MiotDevice, MiotMapping
 
diff --git a/miio/integrations/scishare/__init__.py b/miio/integrations/scishare/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/scishare/coffee/__init__.py b/miio/integrations/scishare/coffee/__init__.py
new file mode 100644
index 000000000..5df7fceaf
--- /dev/null
+++ b/miio/integrations/scishare/coffee/__init__.py
@@ -0,0 +1,3 @@
+from .scishare_coffeemaker import ScishareCoffee
+
+__all__ = ["ScishareCoffee"]
diff --git a/miio/scishare_coffeemaker.py b/miio/integrations/scishare/coffee/scishare_coffeemaker.py
similarity index 98%
rename from miio/scishare_coffeemaker.py
rename to miio/integrations/scishare/coffee/scishare_coffeemaker.py
index fc18c53d2..06ab8e1a7 100644
--- a/miio/scishare_coffeemaker.py
+++ b/miio/integrations/scishare/coffee/scishare_coffeemaker.py
@@ -3,8 +3,8 @@
 
 import click
 
-from .click_common import command, format_output
-from .device import Device
+from miio import Device
+from miio.click_common import command, format_output
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/integrations/shuii/__init__.py b/miio/integrations/shuii/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/humidifier/shuii/__init__.py b/miio/integrations/shuii/humidifier/__init__.py
similarity index 100%
rename from miio/integrations/humidifier/shuii/__init__.py
rename to miio/integrations/shuii/humidifier/__init__.py
diff --git a/miio/integrations/humidifier/shuii/airhumidifier_jsq.py b/miio/integrations/shuii/humidifier/airhumidifier_jsq.py
similarity index 100%
rename from miio/integrations/humidifier/shuii/airhumidifier_jsq.py
rename to miio/integrations/shuii/humidifier/airhumidifier_jsq.py
diff --git a/miio/integrations/tinymu/__init__.py b/miio/integrations/tinymu/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/tinymu/toiletlid/__init__.py b/miio/integrations/tinymu/toiletlid/__init__.py
new file mode 100644
index 000000000..a09499dab
--- /dev/null
+++ b/miio/integrations/tinymu/toiletlid/__init__.py
@@ -0,0 +1,3 @@
+from .toiletlid import Toiletlid
+
+__all__ = ["Toiletlid"]
diff --git a/miio/toiletlid.py b/miio/integrations/tinymu/toiletlid/toiletlid.py
similarity index 97%
rename from miio/toiletlid.py
rename to miio/integrations/tinymu/toiletlid/toiletlid.py
index f9509770b..9c53605de 100644
--- a/miio/toiletlid.py
+++ b/miio/integrations/tinymu/toiletlid/toiletlid.py
@@ -4,8 +4,8 @@
 
 import click
 
-from .click_common import EnumType, command, format_output
-from .device import Device, DeviceStatus
+from miio import Device, DeviceStatus
+from miio.click_common import EnumType, command, format_output
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/integrations/vacuum/__init__.py b/miio/integrations/vacuum/__init__.py
deleted file mode 100644
index 0718196e4..000000000
--- a/miio/integrations/vacuum/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# flake8: noqa
-from .dreame import *
-from .mijia import *
-from .roborock import *
-from .roidmi import *
-from .viomi import *
diff --git a/miio/integrations/viomi/__init__.py b/miio/integrations/viomi/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/vacuum/viomi/__init__.py b/miio/integrations/viomi/viomi/__init__.py
similarity index 100%
rename from miio/integrations/vacuum/viomi/__init__.py
rename to miio/integrations/viomi/viomi/__init__.py
diff --git a/miio/integrations/vacuum/viomi/viomivacuum.py b/miio/integrations/viomi/viomi/viomivacuum.py
similarity index 99%
rename from miio/integrations/vacuum/viomi/viomivacuum.py
rename to miio/integrations/viomi/viomi/viomivacuum.py
index e0de5de06..575290272 100644
--- a/miio/integrations/vacuum/viomi/viomivacuum.py
+++ b/miio/integrations/viomi/viomi/viomivacuum.py
@@ -55,7 +55,7 @@
 from miio.device import Device
 from miio.devicestatus import action, sensor, setting
 from miio.exceptions import DeviceException
-from miio.integrations.vacuum.roborock.vacuumcontainers import (
+from miio.integrations.roborock.vacuum.vacuumcontainers import (  # TODO: remove roborock import
     ConsumableStatus,
     DNDStatus,
 )
diff --git a/miio/integrations/viomidishwasher/__init__.py b/miio/integrations/viomi/viomidishwasher/__init__.py
similarity index 100%
rename from miio/integrations/viomidishwasher/__init__.py
rename to miio/integrations/viomi/viomidishwasher/__init__.py
diff --git a/miio/integrations/viomidishwasher/viomidishwasher.py b/miio/integrations/viomi/viomidishwasher/viomidishwasher.py
similarity index 100%
rename from miio/integrations/viomidishwasher/viomidishwasher.py
rename to miio/integrations/viomi/viomidishwasher/viomidishwasher.py
diff --git a/miio/integrations/xiaomi/__init__.py b/miio/integrations/xiaomi/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/xiaomi/aircondition/__init__.py b/miio/integrations/xiaomi/aircondition/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/airconditioner_miot.py b/miio/integrations/xiaomi/aircondition/airconditioner_miot.py
similarity index 99%
rename from miio/airconditioner_miot.py
rename to miio/integrations/xiaomi/aircondition/airconditioner_miot.py
index 55ba04db4..2443fa74b 100644
--- a/miio/airconditioner_miot.py
+++ b/miio/integrations/xiaomi/aircondition/airconditioner_miot.py
@@ -5,8 +5,8 @@
 
 import click
 
-from .click_common import EnumType, command, format_output
-from .miot_device import DeviceStatus, MiotDevice
+from miio import DeviceStatus, MiotDevice
+from miio.click_common import EnumType, command, format_output
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/integrations/xiaomi/repeater/__init__.py b/miio/integrations/xiaomi/repeater/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/wifirepeater.py b/miio/integrations/xiaomi/repeater/wifirepeater.py
similarity index 97%
rename from miio/wifirepeater.py
rename to miio/integrations/xiaomi/repeater/wifirepeater.py
index ab98677ac..37889d20a 100644
--- a/miio/wifirepeater.py
+++ b/miio/integrations/xiaomi/repeater/wifirepeater.py
@@ -2,8 +2,8 @@
 
 import click
 
-from .click_common import command, format_output
-from .device import Device, DeviceStatus
+from miio import Device, DeviceStatus
+from miio.click_common import command, format_output
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/integrations/xiaomi/wifispeaker/__init__.py b/miio/integrations/xiaomi/wifispeaker/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/wifispeaker.py b/miio/integrations/xiaomi/wifispeaker/wifispeaker.py
similarity index 98%
rename from miio/wifispeaker.py
rename to miio/integrations/xiaomi/wifispeaker/wifispeaker.py
index 35ec3b3c1..e37d11078 100644
--- a/miio/wifispeaker.py
+++ b/miio/integrations/xiaomi/wifispeaker/wifispeaker.py
@@ -3,8 +3,8 @@
 
 import click
 
-from .click_common import command, format_output
-from .device import Device, DeviceStatus
+from miio import Device, DeviceStatus
+from miio.click_common import command, format_output
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/integrations/yeelight/__init__.py b/miio/integrations/yeelight/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/yeelight/dual_switch/__init__.py b/miio/integrations/yeelight/dual_switch/__init__.py
new file mode 100644
index 000000000..bab7e310e
--- /dev/null
+++ b/miio/integrations/yeelight/dual_switch/__init__.py
@@ -0,0 +1,3 @@
+from .yeelight_dual_switch import YeelightDualControlModule
+
+__all__ = ["YeelightDualControlModule"]
diff --git a/miio/yeelight_dual_switch.py b/miio/integrations/yeelight/dual_switch/yeelight_dual_switch.py
similarity index 98%
rename from miio/yeelight_dual_switch.py
rename to miio/integrations/yeelight/dual_switch/yeelight_dual_switch.py
index 5a2bf654e..c5bd9c547 100644
--- a/miio/yeelight_dual_switch.py
+++ b/miio/integrations/yeelight/dual_switch/yeelight_dual_switch.py
@@ -3,8 +3,8 @@
 
 import click
 
-from .click_common import EnumType, command, format_output
-from .miot_device import DeviceStatus, MiotDevice, MiotMapping
+from miio.click_common import EnumType, command, format_output
+from miio.miot_device import DeviceStatus, MiotDevice, MiotMapping
 
 
 class Switch(enum.Enum):
diff --git a/miio/integrations/light/yeelight/__init__.py b/miio/integrations/yeelight/light/__init__.py
similarity index 100%
rename from miio/integrations/light/yeelight/__init__.py
rename to miio/integrations/yeelight/light/__init__.py
diff --git a/miio/integrations/light/yeelight/spec_helper.py b/miio/integrations/yeelight/light/spec_helper.py
similarity index 100%
rename from miio/integrations/light/yeelight/spec_helper.py
rename to miio/integrations/yeelight/light/spec_helper.py
diff --git a/miio/integrations/light/yeelight/specs.yaml b/miio/integrations/yeelight/light/specs.yaml
similarity index 100%
rename from miio/integrations/light/yeelight/specs.yaml
rename to miio/integrations/yeelight/light/specs.yaml
diff --git a/miio/integrations/light/yeelight/yeelight.py b/miio/integrations/yeelight/light/yeelight.py
similarity index 100%
rename from miio/integrations/light/yeelight/yeelight.py
rename to miio/integrations/yeelight/light/yeelight.py
diff --git a/miio/integrations/yunmi/__init__.py b/miio/integrations/yunmi/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/yunmi/waterpurifier/__init__.py b/miio/integrations/yunmi/waterpurifier/__init__.py
new file mode 100644
index 000000000..299addf2a
--- /dev/null
+++ b/miio/integrations/yunmi/waterpurifier/__init__.py
@@ -0,0 +1,4 @@
+from .waterpurifier import WaterPurifier
+from .waterpurifier_yunmi import WaterPurifierYunmi
+
+__all__ = ["WaterPurifier", "WaterPurifierYunmi"]
diff --git a/miio/waterpurifier.py b/miio/integrations/yunmi/waterpurifier/waterpurifier.py
similarity index 97%
rename from miio/waterpurifier.py
rename to miio/integrations/yunmi/waterpurifier/waterpurifier.py
index fa3c431c7..932fbcb57 100644
--- a/miio/waterpurifier.py
+++ b/miio/integrations/yunmi/waterpurifier/waterpurifier.py
@@ -1,8 +1,8 @@
 import logging
 from typing import Any, Dict
 
-from .click_common import command, format_output
-from .device import Device, DeviceStatus
+from miio import Device, DeviceStatus
+from miio.click_common import command, format_output
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/waterpurifier_yunmi.py b/miio/integrations/yunmi/waterpurifier/waterpurifier_yunmi.py
similarity index 99%
rename from miio/waterpurifier_yunmi.py
rename to miio/integrations/yunmi/waterpurifier/waterpurifier_yunmi.py
index 30d0b7c88..bfcd6d5b9 100644
--- a/miio/waterpurifier_yunmi.py
+++ b/miio/integrations/yunmi/waterpurifier/waterpurifier_yunmi.py
@@ -2,8 +2,8 @@
 from datetime import timedelta
 from typing import Any, Dict, List
 
-from .click_common import command, format_output
-from .device import Device, DeviceStatus
+from miio import Device, DeviceStatus
+from miio.click_common import command, format_output
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/integrations/zhimi/__init__.py b/miio/integrations/zhimi/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/airpurifier/zhimi/__init__.py b/miio/integrations/zhimi/airpurifier/__init__.py
similarity index 100%
rename from miio/integrations/airpurifier/zhimi/__init__.py
rename to miio/integrations/zhimi/airpurifier/__init__.py
diff --git a/miio/integrations/airpurifier/zhimi/airfilter_util.py b/miio/integrations/zhimi/airpurifier/airfilter_util.py
similarity index 100%
rename from miio/integrations/airpurifier/zhimi/airfilter_util.py
rename to miio/integrations/zhimi/airpurifier/airfilter_util.py
diff --git a/miio/integrations/airpurifier/zhimi/airfresh.py b/miio/integrations/zhimi/airpurifier/airfresh.py
similarity index 100%
rename from miio/integrations/airpurifier/zhimi/airfresh.py
rename to miio/integrations/zhimi/airpurifier/airfresh.py
diff --git a/miio/integrations/airpurifier/zhimi/airpurifier.py b/miio/integrations/zhimi/airpurifier/airpurifier.py
similarity index 100%
rename from miio/integrations/airpurifier/zhimi/airpurifier.py
rename to miio/integrations/zhimi/airpurifier/airpurifier.py
diff --git a/miio/integrations/airpurifier/zhimi/airpurifier_miot.py b/miio/integrations/zhimi/airpurifier/airpurifier_miot.py
similarity index 100%
rename from miio/integrations/airpurifier/zhimi/airpurifier_miot.py
rename to miio/integrations/zhimi/airpurifier/airpurifier_miot.py
diff --git a/miio/integrations/fan/zhimi/__init__.py b/miio/integrations/zhimi/fan/__init__.py
similarity index 100%
rename from miio/integrations/fan/zhimi/__init__.py
rename to miio/integrations/zhimi/fan/__init__.py
diff --git a/miio/integrations/fan/zhimi/fan.py b/miio/integrations/zhimi/fan/fan.py
similarity index 100%
rename from miio/integrations/fan/zhimi/fan.py
rename to miio/integrations/zhimi/fan/fan.py
diff --git a/miio/integrations/fan/zhimi/zhimi_fan.yaml b/miio/integrations/zhimi/fan/zhimi_fan.yaml
similarity index 100%
rename from miio/integrations/fan/zhimi/zhimi_fan.yaml
rename to miio/integrations/zhimi/fan/zhimi_fan.yaml
diff --git a/miio/integrations/fan/zhimi/zhimi_miot.py b/miio/integrations/zhimi/fan/zhimi_miot.py
similarity index 100%
rename from miio/integrations/fan/zhimi/zhimi_miot.py
rename to miio/integrations/zhimi/fan/zhimi_miot.py
diff --git a/miio/integrations/zhimi/heater/__init__.py b/miio/integrations/zhimi/heater/__init__.py
new file mode 100644
index 000000000..ee17e176c
--- /dev/null
+++ b/miio/integrations/zhimi/heater/__init__.py
@@ -0,0 +1,4 @@
+from .heater import Heater
+from .heater_miot import HeaterMiot
+
+__all__ = ["Heater", "HeaterMiot"]
diff --git a/miio/heater.py b/miio/integrations/zhimi/heater/heater.py
similarity index 98%
rename from miio/heater.py
rename to miio/integrations/zhimi/heater/heater.py
index 1e0abfe89..990dd060b 100644
--- a/miio/heater.py
+++ b/miio/integrations/zhimi/heater/heater.py
@@ -4,8 +4,8 @@
 
 import click
 
-from .click_common import EnumType, command, format_output
-from .device import Device, DeviceStatus
+from miio import Device, DeviceStatus
+from miio.click_common import EnumType, command, format_output
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/miio/heater_miot.py b/miio/integrations/zhimi/heater/heater_miot.py
similarity index 98%
rename from miio/heater_miot.py
rename to miio/integrations/zhimi/heater/heater_miot.py
index 69aa9326c..eba021e8b 100644
--- a/miio/heater_miot.py
+++ b/miio/integrations/zhimi/heater/heater_miot.py
@@ -4,8 +4,8 @@
 
 import click
 
-from .click_common import EnumType, command, format_output
-from .miot_device import DeviceStatus, MiotDevice
+from miio import DeviceStatus, MiotDevice
+from miio.click_common import EnumType, command, format_output
 
 _LOGGER = logging.getLogger(__name__)
 _MAPPINGS = {
diff --git a/miio/integrations/humidifier/zhimi/__init__.py b/miio/integrations/zhimi/humidifier/__init__.py
similarity index 100%
rename from miio/integrations/humidifier/zhimi/__init__.py
rename to miio/integrations/zhimi/humidifier/__init__.py
diff --git a/miio/integrations/humidifier/zhimi/airhumidifier.py b/miio/integrations/zhimi/humidifier/airhumidifier.py
similarity index 100%
rename from miio/integrations/humidifier/zhimi/airhumidifier.py
rename to miio/integrations/zhimi/humidifier/airhumidifier.py
diff --git a/miio/integrations/humidifier/zhimi/airhumidifier_miot.py b/miio/integrations/zhimi/humidifier/airhumidifier_miot.py
similarity index 100%
rename from miio/integrations/humidifier/zhimi/airhumidifier_miot.py
rename to miio/integrations/zhimi/humidifier/airhumidifier_miot.py
diff --git a/miio/integrations/zimi/__init__.py b/miio/integrations/zimi/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/zimi/clock/__init__.py b/miio/integrations/zimi/clock/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/alarmclock.py b/miio/integrations/zimi/clock/alarmclock.py
similarity index 98%
rename from miio/alarmclock.py
rename to miio/integrations/zimi/clock/alarmclock.py
index 2451b84ab..ac12ce7c3 100644
--- a/miio/alarmclock.py
+++ b/miio/integrations/zimi/clock/alarmclock.py
@@ -3,8 +3,8 @@
 
 import click
 
-from .click_common import EnumType, command
-from .device import Device, DeviceStatus
+from miio import Device, DeviceStatus
+from miio.click_common import EnumType, command
 
 
 class HourlySystem(enum.Enum):
diff --git a/miio/integrations/zimi/powerstrip/__init__.py b/miio/integrations/zimi/powerstrip/__init__.py
new file mode 100644
index 000000000..2677aa446
--- /dev/null
+++ b/miio/integrations/zimi/powerstrip/__init__.py
@@ -0,0 +1,3 @@
+from .powerstrip import PowerStrip
+
+__all__ = ["PowerStrip"]
diff --git a/miio/powerstrip.py b/miio/integrations/zimi/powerstrip/powerstrip.py
similarity index 97%
rename from miio/powerstrip.py
rename to miio/integrations/zimi/powerstrip/powerstrip.py
index 91337175f..5487d4e97 100644
--- a/miio/powerstrip.py
+++ b/miio/integrations/zimi/powerstrip/powerstrip.py
@@ -5,10 +5,10 @@
 
 import click
 
-from .click_common import EnumType, command, format_output
-from .device import Device
-from .devicestatus import DeviceStatus, sensor, setting
-from .utils import deprecated
+from miio import Device, DeviceStatus
+from miio.click_common import EnumType, command, format_output
+from miio.devicestatus import sensor, setting
+from miio.utils import deprecated
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/pyproject.toml b/pyproject.toml
index 9b26e8af9..24591a70e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -22,7 +22,7 @@ classifiers = [
 ]
 
 [tool.poetry.scripts]
-mirobo = "miio.integrations.vacuum.roborock.vacuum_cli:cli"
+mirobo = "miio.integrations.roborock.vacuum.vacuum_cli:cli"
 miio-extract-tokens = "miio.extract_tokens:main"
 miiocli = "miio.cli:create_cli"
 


Test patch:
diff --git a/miio/integrations/airpurifier/dmaker/tests/__init__.py b/miio/integrations/airdog/airpurifier/tests/__init__.py
similarity index 100%
rename from miio/integrations/airpurifier/dmaker/tests/__init__.py
rename to miio/integrations/airdog/airpurifier/tests/__init__.py
diff --git a/miio/integrations/airpurifier/airdog/tests/test_airpurifier_airdog.py b/miio/integrations/airdog/airpurifier/tests/test_airpurifier_airdog.py
similarity index 100%
rename from miio/integrations/airpurifier/airdog/tests/test_airpurifier_airdog.py
rename to miio/integrations/airdog/airpurifier/tests/test_airpurifier_airdog.py
diff --git a/miio/tests/test_airqualitymonitor.py b/miio/integrations/cgllc/airmonitor/test_airqualitymonitor.py
similarity index 98%
rename from miio/tests/test_airqualitymonitor.py
rename to miio/integrations/cgllc/airmonitor/test_airqualitymonitor.py
index 5f24fa3da..927f11502 100644
--- a/miio/tests/test_airqualitymonitor.py
+++ b/miio/integrations/cgllc/airmonitor/test_airqualitymonitor.py
@@ -2,16 +2,16 @@
 
 import pytest
 
-from miio import AirQualityMonitor
-from miio.airqualitymonitor import (
+from miio.tests.dummies import DummyDevice
+
+from .airqualitymonitor import (
     MODEL_AIRQUALITYMONITOR_B1,
     MODEL_AIRQUALITYMONITOR_S1,
     MODEL_AIRQUALITYMONITOR_V1,
+    AirQualityMonitor,
     AirQualityMonitorStatus,
 )
 
-from .dummies import DummyDevice
-
 
 class DummyAirQualityMonitorV1(DummyDevice, AirQualityMonitor):
     def __init__(self, *args, **kwargs):
diff --git a/miio/tests/test_airqualitymonitor_miot.py b/miio/integrations/cgllc/airmonitor/test_airqualitymonitor_miot.py
similarity index 96%
rename from miio/tests/test_airqualitymonitor_miot.py
rename to miio/integrations/cgllc/airmonitor/test_airqualitymonitor_miot.py
index b1fc09858..5733b27d9 100644
--- a/miio/tests/test_airqualitymonitor_miot.py
+++ b/miio/integrations/cgllc/airmonitor/test_airqualitymonitor_miot.py
@@ -2,10 +2,13 @@
 
 import pytest
 
-from miio import AirQualityMonitorCGDN1
-from miio.airqualitymonitor_miot import ChargingState, DisplayTemperatureUnitCGDN1
+from miio.tests.dummies import DummyMiotDevice
 
-from .dummies import DummyMiotDevice
+from .airqualitymonitor_miot import (
+    AirQualityMonitorCGDN1,
+    ChargingState,
+    DisplayTemperatureUnitCGDN1,
+)
 
 _INITIAL_STATE = {
     "humidity": 34,
diff --git a/miio/tests/test_chuangmi_plug.py b/miio/integrations/chuangmi/plug/test_chuangmi_plug.py
similarity index 98%
rename from miio/tests/test_chuangmi_plug.py
rename to miio/integrations/chuangmi/plug/test_chuangmi_plug.py
index 4d2cfcf50..624a1b26e 100644
--- a/miio/tests/test_chuangmi_plug.py
+++ b/miio/integrations/chuangmi/plug/test_chuangmi_plug.py
@@ -2,16 +2,16 @@
 
 import pytest
 
-from miio import ChuangmiPlug
-from miio.chuangmi_plug import (
+from miio.tests.dummies import DummyDevice
+
+from .chuangmi_plug import (
     MODEL_CHUANGMI_PLUG_M1,
     MODEL_CHUANGMI_PLUG_V1,
     MODEL_CHUANGMI_PLUG_V3,
+    ChuangmiPlug,
     ChuangmiPlugStatus,
 )
 
-from .dummies import DummyDevice
-
 
 class DummyChuangmiPlugV1(DummyDevice, ChuangmiPlug):
     def __init__(self, *args, **kwargs):
diff --git a/miio/tests/test_chuangmi_ir.json b/miio/integrations/chuangmi/remote/test_chuangmi_ir.json
similarity index 100%
rename from miio/tests/test_chuangmi_ir.json
rename to miio/integrations/chuangmi/remote/test_chuangmi_ir.json
diff --git a/miio/tests/test_chuangmi_ir.py b/miio/integrations/chuangmi/remote/test_chuangmi_ir.py
similarity index 98%
rename from miio/tests/test_chuangmi_ir.py
rename to miio/integrations/chuangmi/remote/test_chuangmi_ir.py
index 4c344c1e2..3ad664903 100644
--- a/miio/tests/test_chuangmi_ir.py
+++ b/miio/integrations/chuangmi/remote/test_chuangmi_ir.py
@@ -5,9 +5,9 @@
 
 import pytest
 
-from miio import ChuangmiIr
+from miio.tests.dummies import DummyDevice
 
-from .dummies import DummyDevice
+from .chuangmi_ir import ChuangmiIr
 
 with open(os.path.join(os.path.dirname(__file__), "test_chuangmi_ir.json")) as inp:
     test_data = json.load(inp)
diff --git a/miio/integrations/humidifier/zhimi/tests/__init__.py b/miio/integrations/deerma/humidifier/tests/__init__.py
similarity index 100%
rename from miio/integrations/humidifier/zhimi/tests/__init__.py
rename to miio/integrations/deerma/humidifier/tests/__init__.py
diff --git a/miio/integrations/humidifier/deerma/tests/test_airhumidifier_jsqs.py b/miio/integrations/deerma/humidifier/tests/test_airhumidifier_jsqs.py
similarity index 100%
rename from miio/integrations/humidifier/deerma/tests/test_airhumidifier_jsqs.py
rename to miio/integrations/deerma/humidifier/tests/test_airhumidifier_jsqs.py
diff --git a/miio/integrations/humidifier/deerma/tests/test_airhumidifier_mjjsq.py b/miio/integrations/deerma/humidifier/tests/test_airhumidifier_mjjsq.py
similarity index 100%
rename from miio/integrations/humidifier/deerma/tests/test_airhumidifier_mjjsq.py
rename to miio/integrations/deerma/humidifier/tests/test_airhumidifier_mjjsq.py
diff --git a/miio/integrations/light/yeelight/tests/__init__.py b/miio/integrations/dmaker/airfresh/tests/__init__.py
similarity index 100%
rename from miio/integrations/light/yeelight/tests/__init__.py
rename to miio/integrations/dmaker/airfresh/tests/__init__.py
diff --git a/miio/integrations/airpurifier/dmaker/tests/test_airfresh_t2017.py b/miio/integrations/dmaker/airfresh/tests/test_airfresh_t2017.py
similarity index 100%
rename from miio/integrations/airpurifier/dmaker/tests/test_airfresh_t2017.py
rename to miio/integrations/dmaker/airfresh/tests/test_airfresh_t2017.py
diff --git a/miio/integrations/fan/dmaker/test_fan.py b/miio/integrations/dmaker/fan/test_fan.py
similarity index 100%
rename from miio/integrations/fan/dmaker/test_fan.py
rename to miio/integrations/dmaker/fan/test_fan.py
diff --git a/miio/integrations/fan/dmaker/test_fan_miot.py b/miio/integrations/dmaker/fan/test_fan_miot.py
similarity index 100%
rename from miio/integrations/fan/dmaker/test_fan_miot.py
rename to miio/integrations/dmaker/fan/test_fan_miot.py
diff --git a/miio/integrations/vacuum/dreame/tests/__init__.py b/miio/integrations/dreame/vacuum/tests/__init__.py
similarity index 100%
rename from miio/integrations/vacuum/dreame/tests/__init__.py
rename to miio/integrations/dreame/vacuum/tests/__init__.py
diff --git a/miio/integrations/vacuum/dreame/tests/test_dreamevacuum_miot.py b/miio/integrations/dreame/vacuum/tests/test_dreamevacuum_miot.py
similarity index 100%
rename from miio/integrations/vacuum/dreame/tests/test_dreamevacuum_miot.py
rename to miio/integrations/dreame/vacuum/tests/test_dreamevacuum_miot.py
diff --git a/miio/integrations/vacuum/mijia/tests/__init__.py b/miio/integrations/genericmiot/tests/__init__.py
similarity index 100%
rename from miio/integrations/vacuum/mijia/tests/__init__.py
rename to miio/integrations/genericmiot/tests/__init__.py
diff --git a/miio/tests/test_huizuo.py b/miio/integrations/huayi/light/test_huizuo.py
similarity index 94%
rename from miio/tests/test_huizuo.py
rename to miio/integrations/huayi/light/test_huizuo.py
index fa40c3d45..f546ac0a2 100644
--- a/miio/tests/test_huizuo.py
+++ b/miio/integrations/huayi/light/test_huizuo.py
@@ -2,13 +2,13 @@
 
 import pytest
 
-from miio import Huizuo, HuizuoLampFan, HuizuoLampHeater, UnsupportedFeatureException
-from miio.huizuo import MODEL_HUIZUO_FANWY  # Fan model extended
-from miio.huizuo import MODEL_HUIZUO_FANWY2  # Fan model basic
-from miio.huizuo import MODEL_HUIZUO_PIS123  # Basic model
-from miio.huizuo import MODEL_HUIZUO_WYHEAT  # Heater model
+from miio.tests.dummies import DummyMiotDevice
 
-from .dummies import DummyMiotDevice
+from .huizuo import MODEL_HUIZUO_FANWY  # Fan model extended
+from .huizuo import MODEL_HUIZUO_FANWY2  # Fan model basic
+from .huizuo import MODEL_HUIZUO_PIS123  # Basic model
+from .huizuo import MODEL_HUIZUO_WYHEAT  # Heater model
+from .huizuo import Huizuo, HuizuoLampFan, HuizuoLampHeater, UnsupportedFeatureException
 
 _INITIAL_STATE = {
     "power": True,
diff --git a/miio/integrations/vacuum/mijia/tests/test_pro2vacuum.py b/miio/integrations/ijai/vacuum/test_pro2vacuum.py
similarity index 98%
rename from miio/integrations/vacuum/mijia/tests/test_pro2vacuum.py
rename to miio/integrations/ijai/vacuum/test_pro2vacuum.py
index b336a917c..bb992861f 100644
--- a/miio/integrations/vacuum/mijia/tests/test_pro2vacuum.py
+++ b/miio/integrations/ijai/vacuum/test_pro2vacuum.py
@@ -3,14 +3,14 @@
 
 import pytest
 
-from miio import Pro2Vacuum
 from miio.tests.dummies import DummyMiotDevice
 
-from ..pro2vacuum import (
+from .pro2vacuum import (
     ERROR_CODES,
     MI_ROBOT_VACUUM_MOP_PRO_2,
     DeviceState,
     FanSpeedMode,
+    Pro2Vacuum,
     SweepMode,
     SweepType,
     WaterLevel,
diff --git a/miio/tests/test_walkingpad.py b/miio/integrations/ksmb/walkingpad/test_walkingpad.py
similarity index 96%
rename from miio/tests/test_walkingpad.py
rename to miio/integrations/ksmb/walkingpad/test_walkingpad.py
index d5cd6ba5b..54d0ca297 100644
--- a/miio/tests/test_walkingpad.py
+++ b/miio/integrations/ksmb/walkingpad/test_walkingpad.py
@@ -3,10 +3,15 @@
 
 import pytest
 
-from miio import DeviceException, Walkingpad
-from miio.walkingpad import OperationMode, OperationSensitivity, WalkingpadStatus
-
-from .dummies import DummyDevice
+from miio import DeviceException
+from miio.tests.dummies import DummyDevice
+
+from .walkingpad import (
+    OperationMode,
+    OperationSensitivity,
+    Walkingpad,
+    WalkingpadStatus,
+)
 
 
 class DummyWalkingpad(DummyDevice, Walkingpad):
diff --git a/miio/integrations/leshow/fan/tests/__init__.py b/miio/integrations/leshow/fan/tests/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/fan/leshow/tests/test_fan_leshow.py b/miio/integrations/leshow/fan/tests/test_fan_leshow.py
similarity index 100%
rename from miio/integrations/fan/leshow/tests/test_fan_leshow.py
rename to miio/integrations/leshow/fan/tests/test_fan_leshow.py
diff --git a/miio/tests/test_airconditioningcompanion.json b/miio/integrations/lumi/acpartner/test_airconditioningcompanion.json
similarity index 100%
rename from miio/tests/test_airconditioningcompanion.json
rename to miio/integrations/lumi/acpartner/test_airconditioningcompanion.json
diff --git a/miio/tests/test_airconditioningcompanion.py b/miio/integrations/lumi/acpartner/test_airconditioningcompanion.py
similarity index 96%
rename from miio/tests/test_airconditioningcompanion.py
rename to miio/integrations/lumi/acpartner/test_airconditioningcompanion.py
index 7b84b744e..8d79bc54f 100644
--- a/miio/tests/test_airconditioningcompanion.py
+++ b/miio/integrations/lumi/acpartner/test_airconditioningcompanion.py
@@ -5,29 +5,30 @@
 
 import pytest
 
-from miio import (
-    AirConditioningCompanion,
-    AirConditioningCompanionMcn02,
-    AirConditioningCompanionV3,
-)
-from miio.airconditioningcompanion import (
+from miio.tests.dummies import DummyDevice
+
+from .airconditioningcompanion import (
     MODEL_ACPARTNER_V3,
     STORAGE_SLOT_ID,
+    AirConditioningCompanion,
     AirConditioningCompanionStatus,
+    AirConditioningCompanionV3,
     FanSpeed,
     Led,
     OperationMode,
     Power,
     SwingMode,
 )
-from miio.airconditioningcompanionMCN import MODEL_ACPARTNER_MCN02
-from miio.airconditioningcompanionMCN import (
+from .airconditioningcompanionMCN import (
+    MODEL_ACPARTNER_MCN02,
+    AirConditioningCompanionMcn02,
+)
+from .airconditioningcompanionMCN import (
     AirConditioningCompanionStatus as AirConditioningCompanionStatusMcn02,
 )
-from miio.airconditioningcompanionMCN import FanSpeed as FanSpeedMcn02
-from miio.airconditioningcompanionMCN import OperationMode as OperationModeMcn02
-from miio.airconditioningcompanionMCN import SwingMode as SwingModeMcn02
-from miio.tests.dummies import DummyDevice
+from .airconditioningcompanionMCN import FanSpeed as FanSpeedMcn02
+from .airconditioningcompanionMCN import OperationMode as OperationModeMcn02
+from .airconditioningcompanionMCN import SwingMode as SwingModeMcn02
 
 STATE_ON = ["on"]
 STATE_OFF = ["off"]
diff --git a/miio/integrations/mmgg/petwaterdispenser/tests/__init__.py b/miio/integrations/mmgg/petwaterdispenser/tests/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/petwaterdispenser/tests/test_status.py b/miio/integrations/mmgg/petwaterdispenser/tests/test_status.py
similarity index 100%
rename from miio/integrations/petwaterdispenser/tests/test_status.py
rename to miio/integrations/mmgg/petwaterdispenser/tests/test_status.py
diff --git a/miio/tests/test_airdehumidifier.py b/miio/integrations/nwt/dehumidifier/test_airdehumidifier.py
similarity index 98%
rename from miio/tests/test_airdehumidifier.py
rename to miio/integrations/nwt/dehumidifier/test_airdehumidifier.py
index 5e53f53f2..dd6c96acb 100644
--- a/miio/tests/test_airdehumidifier.py
+++ b/miio/integrations/nwt/dehumidifier/test_airdehumidifier.py
@@ -2,16 +2,16 @@
 
 import pytest
 
-from miio import AirDehumidifier
-from miio.airdehumidifier import (
+from miio.device import DeviceInfo
+from miio.tests.dummies import DummyDevice
+
+from .airdehumidifier import (
     MODEL_DEHUMIDIFIER_V1,
+    AirDehumidifier,
     AirDehumidifierStatus,
     FanSpeed,
     OperationMode,
 )
-from miio.device import DeviceInfo
-
-from .dummies import DummyDevice
 
 
 class DummyAirDehumidifierV1(DummyDevice, AirDehumidifier):
diff --git a/miio/integrations/philips/light/tests/__init__.py b/miio/integrations/philips/light/tests/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/light/philips/tests/test_ceil.py b/miio/integrations/philips/light/tests/test_ceil.py
similarity index 100%
rename from miio/integrations/light/philips/tests/test_ceil.py
rename to miio/integrations/philips/light/tests/test_ceil.py
diff --git a/miio/integrations/light/philips/tests/test_philips_bulb.py b/miio/integrations/philips/light/tests/test_philips_bulb.py
similarity index 100%
rename from miio/integrations/light/philips/tests/test_philips_bulb.py
rename to miio/integrations/philips/light/tests/test_philips_bulb.py
diff --git a/miio/integrations/light/philips/tests/test_philips_eyecare.py b/miio/integrations/philips/light/tests/test_philips_eyecare.py
similarity index 100%
rename from miio/integrations/light/philips/tests/test_philips_eyecare.py
rename to miio/integrations/philips/light/tests/test_philips_eyecare.py
diff --git a/miio/integrations/light/philips/tests/test_philips_moonlight.py b/miio/integrations/philips/light/tests/test_philips_moonlight.py
similarity index 100%
rename from miio/integrations/light/philips/tests/test_philips_moonlight.py
rename to miio/integrations/philips/light/tests/test_philips_moonlight.py
diff --git a/miio/integrations/light/philips/tests/test_philips_rwread.py b/miio/integrations/philips/light/tests/test_philips_rwread.py
similarity index 100%
rename from miio/integrations/light/philips/tests/test_philips_rwread.py
rename to miio/integrations/philips/light/tests/test_philips_rwread.py
diff --git a/miio/integrations/roborock/vacuum/tests/__init__.py b/miio/integrations/roborock/vacuum/tests/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/vacuum/roborock/tests/test_mirobo.py b/miio/integrations/roborock/vacuum/tests/test_mirobo.py
similarity index 85%
rename from miio/integrations/vacuum/roborock/tests/test_mirobo.py
rename to miio/integrations/roborock/vacuum/tests/test_mirobo.py
index 81a22294a..39b494084 100644
--- a/miio/integrations/vacuum/roborock/tests/test_mirobo.py
+++ b/miio/integrations/roborock/vacuum/tests/test_mirobo.py
@@ -5,7 +5,7 @@
 
 def test_config_read(mocker):
     """Make sure config file is being read."""
-    x = mocker.patch("miio.integrations.vacuum.roborock.vacuum_cli._read_config")
+    x = mocker.patch("miio.integrations.roborock.vacuum.vacuum_cli._read_config")
     mocker.patch("miio.device.Device.send")
 
     runner = CliRunner()
diff --git a/miio/integrations/vacuum/roborock/tests/test_vacuum.py b/miio/integrations/roborock/vacuum/tests/test_vacuum.py
similarity index 99%
rename from miio/integrations/vacuum/roborock/tests/test_vacuum.py
rename to miio/integrations/roborock/vacuum/tests/test_vacuum.py
index 537f14f9b..9f5e2f392 100644
--- a/miio/integrations/vacuum/roborock/tests/test_vacuum.py
+++ b/miio/integrations/roborock/vacuum/tests/test_vacuum.py
@@ -4,7 +4,7 @@
 
 import pytest
 
-from miio import RoborockVacuum, UnsupportedFeatureException, VacuumStatus
+from miio import RoborockVacuum, UnsupportedFeatureException
 from miio.tests.dummies import DummyDevice
 
 from ..vacuum import (
@@ -15,6 +15,7 @@
     MopMode,
     WaterFlow,
 )
+from ..vacuumcontainers import VacuumStatus
 
 
 class DummyVacuum(DummyDevice, RoborockVacuum):
diff --git a/miio/integrations/roidmi/vacuum/tests/__init__.py b/miio/integrations/roidmi/vacuum/tests/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/vacuum/roidmi/tests/test_roidmivacuum_miot.py b/miio/integrations/roidmi/vacuum/tests/test_roidmivacuum_miot.py
similarity index 99%
rename from miio/integrations/vacuum/roidmi/tests/test_roidmivacuum_miot.py
rename to miio/integrations/roidmi/vacuum/tests/test_roidmivacuum_miot.py
index 9ce6dd043..beb3212e8 100644
--- a/miio/integrations/vacuum/roidmi/tests/test_roidmivacuum_miot.py
+++ b/miio/integrations/roidmi/vacuum/tests/test_roidmivacuum_miot.py
@@ -3,7 +3,7 @@
 
 import pytest
 
-from miio.integrations.vacuum.roborock.vacuumcontainers import DNDStatus
+from miio.integrations.roborock.vacuum.vacuumcontainers import DNDStatus
 from miio.tests.dummies import DummyMiotDevice
 
 from ..roidmivacuum_miot import (
diff --git a/miio/integrations/shuii/humidifier/tests/__init__.py b/miio/integrations/shuii/humidifier/tests/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/humidifier/shuii/tests/test_airhumidifier_jsq.py b/miio/integrations/shuii/humidifier/tests/test_airhumidifier_jsq.py
similarity index 100%
rename from miio/integrations/humidifier/shuii/tests/test_airhumidifier_jsq.py
rename to miio/integrations/shuii/humidifier/tests/test_airhumidifier_jsq.py
diff --git a/miio/tests/test_toiletlid.py b/miio/integrations/tinymu/toiletlid/test_toiletlid.py
similarity index 97%
rename from miio/tests/test_toiletlid.py
rename to miio/integrations/tinymu/toiletlid/test_toiletlid.py
index e80cc2d19..998ab0215 100644
--- a/miio/tests/test_toiletlid.py
+++ b/miio/integrations/tinymu/toiletlid/test_toiletlid.py
@@ -13,14 +13,9 @@
 
 import pytest
 
-from miio.toiletlid import (
-    MODEL_TOILETLID_V1,
-    AmbientLightColor,
-    Toiletlid,
-    ToiletlidStatus,
-)
-
-from .dummies import DummyDevice
+from miio.tests.dummies import DummyDevice
+
+from .toiletlid import MODEL_TOILETLID_V1, AmbientLightColor, Toiletlid, ToiletlidStatus
 
 
 class DummyToiletlidV1(DummyDevice, Toiletlid):
diff --git a/miio/integrations/viomidishwasher/test_viomidishwasher.py b/miio/integrations/viomi/viomidishwasher/test_viomidishwasher.py
similarity index 100%
rename from miio/integrations/viomidishwasher/test_viomidishwasher.py
rename to miio/integrations/viomi/viomidishwasher/test_viomidishwasher.py
diff --git a/miio/tests/test_airconditioner_miot.py b/miio/integrations/xiaomi/aircondition/test_airconditioner_miot.py
similarity index 98%
rename from miio/tests/test_airconditioner_miot.py
rename to miio/integrations/xiaomi/aircondition/test_airconditioner_miot.py
index 93d4834cf..ae0329718 100644
--- a/miio/tests/test_airconditioner_miot.py
+++ b/miio/integrations/xiaomi/aircondition/test_airconditioner_miot.py
@@ -2,16 +2,16 @@
 
 import pytest
 
-from miio import AirConditionerMiot
-from miio.airconditioner_miot import (
+from miio.tests.dummies import DummyMiotDevice
+
+from .airconditioner_miot import (
+    AirConditionerMiot,
     CleaningStatus,
     FanSpeed,
     OperationMode,
     TimerStatus,
 )
 
-from .dummies import DummyMiotDevice
-
 _INITIAL_STATE = {
     "power": False,
     "mode": OperationMode.Cool,
diff --git a/miio/tests/test_wifirepeater.py b/miio/integrations/xiaomi/repeater/test_wifirepeater.py
similarity index 98%
rename from miio/tests/test_wifirepeater.py
rename to miio/integrations/xiaomi/repeater/test_wifirepeater.py
index 5fca85636..58cbb81bd 100644
--- a/miio/tests/test_wifirepeater.py
+++ b/miio/integrations/xiaomi/repeater/test_wifirepeater.py
@@ -2,9 +2,9 @@
 
 import pytest
 
-from miio import WifiRepeater
 from miio.tests.dummies import DummyDevice
-from miio.wifirepeater import WifiRepeaterConfiguration, WifiRepeaterStatus
+
+from .wifirepeater import WifiRepeater, WifiRepeaterConfiguration, WifiRepeaterStatus
 
 
 class DummyWifiRepeater(DummyDevice, WifiRepeater):
diff --git a/miio/tests/test_yeelight_dual_switch.py b/miio/integrations/yeelight/dual_switch/test_yeelight_dual_switch.py
similarity index 96%
rename from miio/tests/test_yeelight_dual_switch.py
rename to miio/integrations/yeelight/dual_switch/test_yeelight_dual_switch.py
index ed38ae008..7af74cbb0 100644
--- a/miio/tests/test_yeelight_dual_switch.py
+++ b/miio/integrations/yeelight/dual_switch/test_yeelight_dual_switch.py
@@ -2,10 +2,9 @@
 
 import pytest
 
-from miio import YeelightDualControlModule
-from miio.yeelight_dual_switch import Switch
+from miio.tests.dummies import DummyMiotDevice
 
-from .dummies import DummyMiotDevice
+from .yeelight_dual_switch import Switch, YeelightDualControlModule
 
 _INITIAL_STATE = {
     "switch_1_state": True,
diff --git a/miio/integrations/yeelight/light/tests/__init__.py b/miio/integrations/yeelight/light/tests/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/light/yeelight/tests/test_yeelight.py b/miio/integrations/yeelight/light/tests/test_yeelight.py
similarity index 100%
rename from miio/integrations/light/yeelight/tests/test_yeelight.py
rename to miio/integrations/yeelight/light/tests/test_yeelight.py
diff --git a/miio/integrations/light/yeelight/tests/test_yeelight_spec_helper.py b/miio/integrations/yeelight/light/tests/test_yeelight_spec_helper.py
similarity index 100%
rename from miio/integrations/light/yeelight/tests/test_yeelight_spec_helper.py
rename to miio/integrations/yeelight/light/tests/test_yeelight_spec_helper.py
diff --git a/miio/tests/test_waterpurifier.py b/miio/integrations/yunmi/waterpurifier/test_waterpurifier.py
similarity index 93%
rename from miio/tests/test_waterpurifier.py
rename to miio/integrations/yunmi/waterpurifier/test_waterpurifier.py
index 4e97218bb..636447477 100644
--- a/miio/tests/test_waterpurifier.py
+++ b/miio/integrations/yunmi/waterpurifier/test_waterpurifier.py
@@ -2,10 +2,9 @@
 
 import pytest
 
-from miio import WaterPurifier
-from miio.waterpurifier import WaterPurifierStatus
+from miio.tests.dummies import DummyDevice
 
-from .dummies import DummyDevice
+from .waterpurifier import WaterPurifier, WaterPurifierStatus
 
 
 class DummyWaterPurifier(DummyDevice, WaterPurifier):
diff --git a/miio/integrations/zhimi/airpurifier/tests/__init__.py b/miio/integrations/zhimi/airpurifier/tests/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/airpurifier/zhimi/tests/test_airfilter_util.py b/miio/integrations/zhimi/airpurifier/tests/test_airfilter_util.py
similarity index 100%
rename from miio/integrations/airpurifier/zhimi/tests/test_airfilter_util.py
rename to miio/integrations/zhimi/airpurifier/tests/test_airfilter_util.py
diff --git a/miio/integrations/airpurifier/zhimi/tests/test_airfresh.py b/miio/integrations/zhimi/airpurifier/tests/test_airfresh.py
similarity index 100%
rename from miio/integrations/airpurifier/zhimi/tests/test_airfresh.py
rename to miio/integrations/zhimi/airpurifier/tests/test_airfresh.py
diff --git a/miio/integrations/airpurifier/zhimi/tests/test_airpurifier.py b/miio/integrations/zhimi/airpurifier/tests/test_airpurifier.py
similarity index 100%
rename from miio/integrations/airpurifier/zhimi/tests/test_airpurifier.py
rename to miio/integrations/zhimi/airpurifier/tests/test_airpurifier.py
diff --git a/miio/integrations/airpurifier/zhimi/tests/test_airpurifier_miot.py b/miio/integrations/zhimi/airpurifier/tests/test_airpurifier_miot.py
similarity index 100%
rename from miio/integrations/airpurifier/zhimi/tests/test_airpurifier_miot.py
rename to miio/integrations/zhimi/airpurifier/tests/test_airpurifier_miot.py
diff --git a/miio/integrations/fan/zhimi/test_fan.py b/miio/integrations/zhimi/fan/test_fan.py
similarity index 100%
rename from miio/integrations/fan/zhimi/test_fan.py
rename to miio/integrations/zhimi/fan/test_fan.py
diff --git a/miio/integrations/fan/zhimi/test_zhimi_miot.py b/miio/integrations/zhimi/fan/test_zhimi_miot.py
similarity index 100%
rename from miio/integrations/fan/zhimi/test_zhimi_miot.py
rename to miio/integrations/zhimi/fan/test_zhimi_miot.py
diff --git a/miio/tests/test_heater.py b/miio/integrations/zhimi/heater/test_heater.py
similarity index 97%
rename from miio/tests/test_heater.py
rename to miio/integrations/zhimi/heater/test_heater.py
index 7aa3cf388..2287a8301 100644
--- a/miio/tests/test_heater.py
+++ b/miio/integrations/zhimi/heater/test_heater.py
@@ -3,9 +3,9 @@
 import pytest
 
 from miio import Heater
-from miio.heater import MODEL_HEATER_ZA1, Brightness, HeaterStatus
+from miio.tests.dummies import DummyDevice
 
-from .dummies import DummyDevice
+from .heater import MODEL_HEATER_ZA1, Brightness, HeaterStatus
 
 
 class DummyHeater(DummyDevice, Heater):
diff --git a/miio/tests/test_heater_miot.py b/miio/integrations/zhimi/heater/test_heater_miot.py
similarity index 97%
rename from miio/tests/test_heater_miot.py
rename to miio/integrations/zhimi/heater/test_heater_miot.py
index 0e8ae842a..388ce4e7d 100644
--- a/miio/tests/test_heater_miot.py
+++ b/miio/integrations/zhimi/heater/test_heater_miot.py
@@ -3,9 +3,9 @@
 import pytest
 
 from miio import HeaterMiot
-from miio.heater_miot import LedBrightness
+from miio.tests.dummies import DummyMiotDevice
 
-from .dummies import DummyMiotDevice
+from .heater_miot import LedBrightness
 
 _INITIAL_STATE = {
     "power": True,
diff --git a/miio/integrations/zhimi/humidifier/tests/__init__.py b/miio/integrations/zhimi/humidifier/tests/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/miio/integrations/humidifier/zhimi/tests/test_airhumidifier.py b/miio/integrations/zhimi/humidifier/tests/test_airhumidifier.py
similarity index 100%
rename from miio/integrations/humidifier/zhimi/tests/test_airhumidifier.py
rename to miio/integrations/zhimi/humidifier/tests/test_airhumidifier.py
diff --git a/miio/integrations/humidifier/zhimi/tests/test_airhumidifier_miot.py b/miio/integrations/zhimi/humidifier/tests/test_airhumidifier_miot.py
similarity index 100%
rename from miio/integrations/humidifier/zhimi/tests/test_airhumidifier_miot.py
rename to miio/integrations/zhimi/humidifier/tests/test_airhumidifier_miot.py
diff --git a/miio/tests/test_powerstrip.py b/miio/integrations/zimi/powerstrip/test_powerstrip.py
similarity index 99%
rename from miio/tests/test_powerstrip.py
rename to miio/integrations/zimi/powerstrip/test_powerstrip.py
index d25032937..602821058 100644
--- a/miio/tests/test_powerstrip.py
+++ b/miio/integrations/zimi/powerstrip/test_powerstrip.py
@@ -3,15 +3,15 @@
 import pytest
 
 from miio import PowerStrip
-from miio.powerstrip import (
+from miio.tests.dummies import DummyDevice
+
+from .powerstrip import (
     MODEL_POWER_STRIP_V1,
     MODEL_POWER_STRIP_V2,
     PowerMode,
     PowerStripStatus,
 )
 
-from .dummies import DummyDevice
-
 
 class DummyPowerStripV1(DummyDevice, PowerStrip):
     def __init__(self, *args, **kwargs):
diff --git a/miio/tests/test_vacuums.py b/miio/tests/test_vacuums.py
index 69f337b0e..b2032f873 100644
--- a/miio/tests/test_vacuums.py
+++ b/miio/tests/test_vacuums.py
@@ -7,7 +7,7 @@
 from pytz import UTC
 
 from miio.device import Device
-from miio.integrations.vacuum.roborock.vacuum import ROCKROBO_V1, Timer
+from miio.integrations.roborock.vacuum.vacuum import ROCKROBO_V1, Timer
 from miio.interfaces import VacuumInterface
 
 # list of all supported vacuum classes