diff --git a/mpf/core/machine.py b/mpf/core/machine.py
index d40f23119..050a488cf 100644
--- a/mpf/core/machine.py
+++ b/mpf/core/machine.py
@@ -68,6 +68,7 @@ if MYPY:   # pragma: no cover
     from mpf.devices.dmd import Dmd
     from mpf.devices.rgb_dmd import RgbDmd
     from mpf.devices.flipper import Flipper
+    from mpf.devices.diverter import Diverter
 
 
 # pylint: disable-msg=too-many-instance-attributes
@@ -172,6 +173,7 @@ class MachineController(LogMixin):
             self.dmds = None                            # type: Dict[str, Dmd]
             self.rgb_dmds = None                        # type: Dict[str, RgbDmd]
             self.flippers = None                        # type: Dict[str, Flipper]
+            self.diverters = None                       # type: Dict[str, Diverter]
 
         self._set_machine_path()
 
diff --git a/mpf/devices/diverter.py b/mpf/devices/diverter.py
index 617f020d1..bee8182a0 100644
--- a/mpf/devices/diverter.py
+++ b/mpf/devices/diverter.py
@@ -168,14 +168,16 @@ class Diverter(SystemWideDevice):
 
     def _coil_activate(self):
         """Activate the coil."""
-        if self.config['type'] == 'pulse':
-            self.config['activation_coil'].pulse()
-        elif self.config['type'] == 'hold':
-            self.config['activation_coil'].enable()
+        if self.config['activation_coil']:
+            if self.config['type'] == 'pulse':
+                self.config['activation_coil'].pulse()
+            elif self.config['type'] == 'hold':
+                self.config['activation_coil'].enable()
 
     def _coil_deactivate(self):
         """Deactivate the coil."""
-        self.config['activation_coil'].disable()
+        if self.config['activation_coil']:
+            self.config['activation_coil'].disable()
 
         if self.config['deactivation_coil']:
             self.config['deactivation_coil'].pulse()
diff --git a/mpf/devices/stepper.py b/mpf/devices/stepper.py
index 29b5e8e60..c3b155a75 100644
--- a/mpf/devices/stepper.py
+++ b/mpf/devices/stepper.py
@@ -45,6 +45,9 @@ class Stepper(SystemWideDevice):
         yield from super()._initialize()
         self.platform = self.machine.get_platform_sections('stepper_controllers', self.config['platform'])
 
+        # first target is the reset position but we might get an early target during startup via events
+        self._target_position = self.config['reset_position']
+
         for position in self.config['named_positions']:
             self.machine.events.add_handler(self.config['named_positions'][position],
                                             self._position_event,
@@ -92,9 +95,9 @@ class Stepper(SystemWideDevice):
         self.debug_log("Homing stepper")
         yield from self._home()
 
-        # move to reset position
-        self.debug_log("Moving to reset position")
-        self.reset()
+        # run the loop at least once
+        self._is_moving.set()
+
         while True:
             # wait until we should be moving
             yield from self._is_moving.wait()
@@ -150,7 +153,7 @@ class Stepper(SystemWideDevice):
         self._is_homed = True
         self._is_moving.clear()
         # home position is 0
-        self._current_position = self._target_position = 0
+        self._current_position = 0
 
     def _post_ready_event(self):
         if not self._ball_search_started:

Better error for diverter without coil
Show a better error message: https://groups.google.com/forum/m/#!topic/mpf-users/YZlYmkEzAkw
diff --git a/mpf/tests/machine_files/diverter/config/only_events_no_coils.yaml b/mpf/tests/machine_files/diverter/config/only_events_no_coils.yaml
new file mode 100644
index 000000000..ce86734cc
--- /dev/null
+++ b/mpf/tests/machine_files/diverter/config/only_events_no_coils.yaml
@@ -0,0 +1,25 @@
+#config_version=5
+
+config:
+- config.yaml
+
+diverters:
+    d_test_with_events:
+        debug: true
+        feeder_devices: test_trough
+        targets_when_active: playfield
+        targets_when_inactive: test_target
+
+servos:
+    s_diverter:
+        number:
+        positions:
+            0.7: diverter_d_test_with_events_activating
+            0.2: diverter_d_test_with_events_deactivating
+
+steppers:
+    s_diverter:
+        number:
+        named_positions:
+            20: diverter_d_test_with_events_activating
+            400: diverter_d_test_with_events_deactivating
diff --git a/mpf/tests/machine_files/diverter/config/test_hold_activation_time.yaml b/mpf/tests/machine_files/diverter/config/test_hold_activation_time.yaml
index 2b91e9eaf..a0d476155 100644
--- a/mpf/tests/machine_files/diverter/config/test_hold_activation_time.yaml
+++ b/mpf/tests/machine_files/diverter/config/test_hold_activation_time.yaml
@@ -12,4 +12,4 @@ diverters:
         targets_when_active: playfield
         targets_when_inactive: test_target
         activation_time: 4s
-        debug: True
\ No newline at end of file
+        debug: True
diff --git a/mpf/tests/test_Diverter.py b/mpf/tests/test_Diverter.py
index 55510f120..c48723360 100644
--- a/mpf/tests/test_Diverter.py
+++ b/mpf/tests/test_Diverter.py
@@ -1,12 +1,9 @@
-from mpf.tests.MpfTestCase import MpfTestCase
+from mpf.tests.MpfTestCase import MpfTestCase, test_config
 from unittest.mock import MagicMock
 
 
 class TestDiverter(MpfTestCase):
 
-    def getConfigFile(self):
-        return self._testMethodName + ".yaml"
-
     def getMachinePath(self):
         return 'tests/machine_files/diverter/'
 
@@ -25,19 +22,69 @@ class TestDiverter(MpfTestCase):
         self.queue = queue
         queue.wait()
 
+    @test_config("only_events_no_coils.yaml")
+    def test_diverter_with_servo_and_stepper(self):
+        self.queue = None
+        diverter = self.machine.diverters["d_test_with_events"]
+        self.advance_time_and_run(.1)
+
+        self.assertEqual(.2, self.machine.servos["s_diverter"].hw_servo.current_position)
+        self.assertEqual(400, self.machine.steppers["s_diverter"].hw_stepper._current_position)
+
+
+        self.assertFalse(diverter.enabled)
+        self.assertFalse(diverter.active)
+
+        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices["test_trough"]
+        self.machine.playfield.add_ball()
+
+        self.advance_time_and_run(1)
+
+        self.assertTrue(diverter.enabled)
+        self.assertTrue(diverter.active)
+        self.assertEqual(.7, self.machine.servos["s_diverter"].hw_servo.current_position)
+        self.assertEqual(20, self.machine.steppers["s_diverter"].hw_stepper._current_position)
+
+        self.hit_and_release_switch("s_playfield")
+        self.machine_run()
+        self.assertFalse(diverter.active)
+
+        self.assertEqual(.2, self.machine.servos["s_diverter"].hw_servo.current_position)
+        self.assertEqual(400, self.machine.steppers["s_diverter"].hw_stepper._current_position)
+
+        self.hit_switch_and_run("s_ball_switch1", 1)
+        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices["test_target"]
+        self.machine.playfield.add_ball()
+
+        self.advance_time_and_run(3)
+        self.assertFalse(diverter.enabled)
+        self.assertFalse(diverter.active)
+
+        self.hit_and_release_switch("s_diverter")
+        self.advance_time_and_run(0.5)
+        self.assertFalse(diverter.enabled)
+        self.assertFalse(diverter.active)
+
+        self.assertEqual(.2, self.machine.servos["s_diverter"].hw_servo.current_position)
+        self.assertEqual(400, self.machine.steppers["s_diverter"].hw_stepper._current_position)
+
+        self.advance_time_and_run(4)
+        self.assertEqual(0, diverter.diverting_ejects_count)
+
+    @test_config("test_delayed_eject.yaml")
     def test_delayed_eject(self):
         self.queue = None
-        diverter = self.machine.diverters.d_test_delayed_eject
+        diverter = self.machine.diverters["d_test_delayed_eject"]
 
-        self.machine.coils.c_diverter.enable = MagicMock()
-        self.machine.coils.c_diverter.disable = MagicMock()
+        self.machine.coils["c_diverter"].enable = MagicMock()
+        self.machine.coils["c_diverter"].disable = MagicMock()
 
         self.assertFalse(diverter.enabled)
         self.assertFalse(diverter.active)
 
         self.machine.events.add_handler("balldevice_test_trough_ball_eject_attempt", self._block_device)
 
-        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices.test_trough
+        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices["test_trough"]
         self.machine.playfield.add_ball()
 
         self.advance_time_and_run(20)
@@ -48,20 +95,20 @@ class TestDiverter(MpfTestCase):
 
         self.assertTrue(diverter.enabled)
         self.assertTrue(diverter.active)
-        self.machine.coils.c_diverter.enable.assert_called_once_with()
-        self.machine.coils.c_diverter.enable = MagicMock()
-        assert not self.machine.coils.c_diverter.disable.called
+        self.machine.coils["c_diverter"].enable.assert_called_once_with()
+        self.machine.coils["c_diverter"].enable = MagicMock()
+        assert not self.machine.coils["c_diverter"].disable.called
 
         self.advance_time_and_run(4)
-        self.machine.coils.c_diverter.disable.assert_called_once_with()
-        assert not self.machine.coils.c_diverter.enable.called
+        self.machine.coils["c_diverter"].disable.assert_called_once_with()
+        assert not self.machine.coils["c_diverter"].enable.called
 
         self.hit_and_release_switch("s_playfield")
         self.machine_run()
         self.assertFalse(diverter.active)
 
         self.hit_switch_and_run("s_ball_switch1", 1)
-        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices.test_target
+        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices["test_target"]
         self.machine.playfield.add_ball()
 
         self.advance_time_and_run(3)
@@ -74,19 +121,20 @@ class TestDiverter(MpfTestCase):
         self.assertFalse(diverter.active)
 
         self.advance_time_and_run(4)
-        assert not self.machine.coils.c_diverter.enable.called
+        assert not self.machine.coils["c_diverter"].enable.called
         self.assertEqual(0, diverter.diverting_ejects_count)
 
+    @test_config("test_hold_activation_time.yaml")
     def test_hold_activation_time(self):
-        diverter = self.machine.diverters.d_test_hold_activation_time
+        diverter = self.machine.diverters["d_test_hold_activation_time"]
 
-        self.machine.coils.c_diverter.enable = MagicMock()
-        self.machine.coils.c_diverter.disable = MagicMock()
+        self.machine.coils["c_diverter"].enable = MagicMock()
+        self.machine.coils["c_diverter"].disable = MagicMock()
 
         self.assertFalse(diverter.enabled)
         self.assertFalse(diverter.active)
 
-        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices.test_trough
+        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices["test_trough"]
         self.machine.playfield.add_ball()
 
         self.advance_time_and_run(1)
@@ -97,20 +145,20 @@ class TestDiverter(MpfTestCase):
         self.advance_time_and_run(0.5)
         self.assertTrue(diverter.enabled)
         self.assertTrue(diverter.active)
-        self.machine.coils.c_diverter.enable.assert_called_once_with()
-        self.machine.coils.c_diverter.enable = MagicMock()
-        assert not self.machine.coils.c_diverter.disable.called
+        self.machine.coils["c_diverter"].enable.assert_called_once_with()
+        self.machine.coils["c_diverter"].enable = MagicMock()
+        assert not self.machine.coils["c_diverter"].disable.called
 
         self.advance_time_and_run(4)
-        self.machine.coils.c_diverter.disable.assert_called_once_with()
-        assert not self.machine.coils.c_diverter.enable.called
+        self.machine.coils["c_diverter"].disable.assert_called_once_with()
+        assert not self.machine.coils["c_diverter"].enable.called
 
         self.hit_and_release_switch("s_playfield")
         self.machine_run()
         self.assertFalse(diverter.active)
 
         self.hit_switch_and_run("s_ball_switch1", 1)
-        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices.test_target
+        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices["test_target"]
         self.machine.playfield.add_ball()
 
         self.advance_time_and_run(3)
@@ -123,22 +171,23 @@ class TestDiverter(MpfTestCase):
         self.assertFalse(diverter.active)
 
         self.advance_time_and_run(4)
-        assert not self.machine.coils.c_diverter.enable.called
+        assert not self.machine.coils["c_diverter"].enable.called
 
+    @test_config("test_hold_no_activation_time.yaml")
     def test_hold_no_activation_time(self):
-        diverter = self.machine.diverters.d_test_hold
+        diverter = self.machine.diverters["d_test_hold"]
 
-        self.assertEqual("idle", self.machine.ball_devices.test_trough._state)
-        self.assertEqual("idle", self.machine.ball_devices.test_target._state)
+        self.assertEqual("idle", self.machine.ball_devices["test_trough"]._state)
+        self.assertEqual("idle", self.machine.ball_devices["test_target"]._state)
 
-        self.machine.coils.c_diverter.enable = MagicMock()
-        self.machine.coils.c_diverter.disable = MagicMock()
+        self.machine.coils["c_diverter"].enable = MagicMock()
+        self.machine.coils["c_diverter"].disable = MagicMock()
 
         self.assertFalse(diverter.enabled)
         self.assertFalse(diverter.active)
 
         # test active side
-        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices.test_trough
+        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices["test_trough"]
         self.machine.playfield.add_ball()
 
         self.advance_time_and_run(1)
@@ -149,21 +198,21 @@ class TestDiverter(MpfTestCase):
         self.advance_time_and_run(0.5)
         self.assertTrue(diverter.enabled)
         self.assertTrue(diverter.active)
-        self.machine.coils.c_diverter.enable.assert_called_once_with()
-        self.machine.coils.c_diverter.enable = MagicMock()
-        assert not self.machine.coils.c_diverter.disable.called
+        self.machine.coils["c_diverter"].enable.assert_called_once_with()
+        self.machine.coils["c_diverter"].enable = MagicMock()
+        assert not self.machine.coils["c_diverter"].disable.called
 
         self.advance_time_and_run(4)
-        assert not self.machine.coils.c_diverter.disable.called
+        assert not self.machine.coils["c_diverter"].disable.called
 
         self.hit_and_release_switch("s_playfield")
         self.machine_run()
         self.assertFalse(diverter.active)
-        self.machine.coils.c_diverter.disable.assert_called_once_with()
+        self.machine.coils["c_diverter"].disable.assert_called_once_with()
 
         self.hit_switch_and_run("s_ball_switch1", 1)
         # test inactive side
-        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices.test_target
+        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices["test_target"]
         self.machine.playfield.add_ball()
 
         self.advance_time_and_run(3)
@@ -176,14 +225,15 @@ class TestDiverter(MpfTestCase):
         self.assertFalse(diverter.active)
 
         self.advance_time_and_run(4)
-        assert not self.machine.coils.c_diverter.enable.called
+        assert not self.machine.coils["c_diverter"].enable.called
 
         self.hit_switch_and_run("s_ball_switch1", 1)
 
+    @test_config("test_missing_ball_at_source.yaml")
     def test_missing_ball_at_source(self):
-        diverter = self.machine.diverters.d_test
-        trough1 = self.machine.ball_devices.test_trough
-        target = self.machine.ball_devices.test_target
+        diverter = self.machine.diverters["d_test"]
+        trough1 = self.machine.ball_devices["test_trough"]
+        target = self.machine.ball_devices["test_target"]
 
         self.machine.default_platform.actions[trough1].set_result("missing")
         trough1.eject(1, target)
@@ -194,12 +244,13 @@ class TestDiverter(MpfTestCase):
 
         self.assertEqual(0, diverter.diverting_ejects_count)
 
+    @test_config("test_eject_to_oposide_sides2.yaml")
     def test_eject_to_oposide_sides2(self):
-        diverter = self.machine.diverters.d_test_hold
-        trough1 = self.machine.ball_devices.test_trough
-        trough2 = self.machine.ball_devices.test_trough2
+        diverter = self.machine.diverters["d_test_hold"]
+        trough1 = self.machine.ball_devices["test_trough"]
+        trough2 = self.machine.ball_devices["test_trough2"]
         playfield = self.machine.playfield
-        target = self.machine.ball_devices.test_target
+        target = self.machine.ball_devices["test_target"]
 
         self.assertEqual(3, trough1.balls)
         self.assertEqual(3, trough2.balls)
@@ -223,18 +274,19 @@ class TestDiverter(MpfTestCase):
         self.assertEqual(0, trough1.balls)
         self.assertEqual(0, trough2.balls)
 
+    @test_config("test_eject_to_oposide_sides.yaml")
     def test_eject_to_oposide_sides(self):
-        diverter = self.machine.diverters.d_test_hold
-        trough1 = self.machine.ball_devices.test_trough
-        trough2 = self.machine.ball_devices.test_trough2
+        diverter = self.machine.diverters["d_test_hold"]
+        trough1 = self.machine.ball_devices["test_trough"]
+        trough2 = self.machine.ball_devices["test_trough2"]
         playfield = self.machine.playfield
-        target = self.machine.ball_devices.test_target
+        target = self.machine.ball_devices["test_target"]
 
-        pulse1 = self.machine.coils.eject_coil1.pulse
-        pulse3 = self.machine.coils.eject_coil3.pulse
+        pulse1 = self.machine.coils["eject_coil1"].pulse
+        pulse3 = self.machine.coils["eject_coil3"].pulse
 
-        self.machine.coils.eject_coil1.pulse = MagicMock(wraps=pulse1)
-        self.machine.coils.eject_coil3.pulse = MagicMock(wraps=pulse3)
+        self.machine.coils["eject_coil1"].pulse = MagicMock(wraps=pulse1)
+        self.machine.coils["eject_coil3"].pulse = MagicMock(wraps=pulse3)
 
         # this goes to the active side of the diverter
         trough1.eject(1, playfield)
@@ -250,25 +302,25 @@ class TestDiverter(MpfTestCase):
         self.assertTrue(diverter.active)
 
         # only trough1 ejects. trought2 waits because of diverter
-        self.assertTrue(self.machine.coils.eject_coil1.pulse.called)
-        assert not self.machine.coils.eject_coil3.pulse.called
+        self.assertTrue(self.machine.coils["eject_coil1"].pulse.called)
+        assert not self.machine.coils["eject_coil3"].pulse.called
         self.assertEqual(1, diverter.diverting_ejects_count)
 
         self.hit_and_release_switch("s_playfield")
         self.advance_time_and_run(3)
         # wait for cooldown
-        self.assertFalse(self.machine.coils.eject_coil3.pulse.called)
+        self.assertFalse(self.machine.coils["eject_coil3"].pulse.called)
         self.assertEqual(1, diverter.diverting_ejects_count)
         self.advance_time_and_run(3)
-        self.assertTrue(self.machine.coils.eject_coil3.pulse.called)
+        self.assertTrue(self.machine.coils["eject_coil3"].pulse.called)
         self.assertEqual(1, diverter.diverting_ejects_count)
         self.assertFalse(diverter.enabled)
         self.assertFalse(diverter.active)
 
-        self.machine.coils.eject_coil1.pulse = MagicMock(wraps=pulse1)
-        self.machine.coils.eject_coil3.pulse = MagicMock(wraps=pulse3)
+        self.machine.coils["eject_coil1"].pulse = MagicMock(wraps=pulse1)
+        self.machine.coils["eject_coil3"].pulse = MagicMock(wraps=pulse3)
 
-        self.machine.ball_devices.test_target.eject()
+        self.machine.ball_devices["test_target"].eject()
         self.advance_time_and_run(20)
 
         self.assertEqual("idle", trough1._state)
@@ -293,8 +345,8 @@ class TestDiverter(MpfTestCase):
         self.assertFalse(diverter.enabled)
         self.assertFalse(diverter.active)
 
-        self.assertTrue(self.machine.coils.eject_coil3.pulse.called)
-        assert not self.machine.coils.eject_coil1.pulse.called
+        self.assertTrue(self.machine.coils["eject_coil3"].pulse.called)
+        assert not self.machine.coils["eject_coil1"].pulse.called
 
         self.hit_and_release_switch("s_playfield")
         self.advance_time_and_run(3)
@@ -307,52 +359,53 @@ class TestDiverter(MpfTestCase):
         self.assertTrue(diverter.enabled)
         self.assertTrue(diverter.active)
 
-        self.assertTrue(self.machine.coils.eject_coil1.pulse.called)
+        self.assertTrue(self.machine.coils["eject_coil1"].pulse.called)
         self.advance_time_and_run(20)
 
         self.assertEqual(0, diverter.diverting_ejects_count)
 
+    @test_config("test_pulsed_activation_time.yaml")
     def test_pulsed_activation_time(self):
-        diverter = self.machine.diverters.d_test_pulse
+        diverter = self.machine.diverters["d_test_pulse"]
 
-        self.machine.coils.c_diverter.pulse = MagicMock()
-        self.machine.coils.c_diverter_disable.pulse = MagicMock()
+        self.machine.coils["c_diverter"].pulse = MagicMock()
+        self.machine.coils["c_diverter_disable"].pulse = MagicMock()
 
         self.post_event("machine_reset_phase_3")
         self.assertFalse(diverter.enabled)
         self.assertFalse(diverter.active)
-        self.assertTrue(self.machine.coils.c_diverter_disable.pulse.called)
-        assert not self.machine.coils.c_diverter.pulse.called
+        self.assertTrue(self.machine.coils["c_diverter_disable"].pulse.called)
+        assert not self.machine.coils["c_diverter"].pulse.called
 
-        self.assertEqual("idle", self.machine.ball_devices.test_trough._state)
-        self.assertEqual("idle", self.machine.ball_devices.test_target._state)
+        self.assertEqual("idle", self.machine.ball_devices["test_trough"]._state)
+        self.assertEqual("idle", self.machine.ball_devices["test_target"]._state)
 
-        self.machine.coils.c_diverter.pulse = MagicMock()
-        self.machine.coils.c_diverter_disable.pulse = MagicMock()
+        self.machine.coils["c_diverter"].pulse = MagicMock()
+        self.machine.coils["c_diverter_disable"].pulse = MagicMock()
 
         self.assertFalse(diverter.enabled)
         self.assertFalse(diverter.active)
 
-        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices.test_trough
+        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices["test_trough"]
         self.machine.playfield.add_ball()
 
         self.advance_time_and_run(1)
         self.assertTrue(diverter.enabled)
         self.assertTrue(diverter.active)
-        self.assertTrue(self.machine.coils.c_diverter.pulse.called)
-        self.machine.coils.c_diverter.pulse = MagicMock()
-        assert not self.machine.coils.c_diverter_disable.pulse.called
+        self.assertTrue(self.machine.coils["c_diverter"].pulse.called)
+        self.machine.coils["c_diverter"].pulse = MagicMock()
+        assert not self.machine.coils["c_diverter_disable"].pulse.called
 
         self.advance_time_and_run(4)
-        assert not self.machine.coils.c_diverter_disable.pulse.called
+        assert not self.machine.coils["c_diverter_disable"].pulse.called
 
         self.hit_and_release_switch("s_playfield")
         self.machine_run()
         self.assertFalse(diverter.active)
-        self.assertTrue(self.machine.coils.c_diverter_disable.pulse.called)
+        self.assertTrue(self.machine.coils["c_diverter_disable"].pulse.called)
 
         self.hit_switch_and_run("s_ball_switch1", 1)
-        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices.test_target
+        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices["test_target"]
         self.machine.playfield.add_ball()
 
         self.advance_time_and_run(3)
@@ -365,11 +418,12 @@ class TestDiverter(MpfTestCase):
         self.assertFalse(diverter.active)
 
         self.advance_time_and_run(4)
-        assert not self.machine.coils.c_diverter.pulse.called
+        assert not self.machine.coils["c_diverter"].pulse.called
         self.assertEqual(0, diverter.diverting_ejects_count)
 
+    @test_config("test_diverter_with_switch.yaml")
     def test_diverter_with_switch(self):
-        diverter = self.machine.diverters.d_test
+        diverter = self.machine.diverters["d_test"]
 
         self.assertFalse(diverter.enabled)
         self.assertFalse(diverter.active)
@@ -417,8 +471,9 @@ class TestDiverter(MpfTestCase):
         self.assertFalse(diverter.enabled)
         self.assertFalse(diverter.active)
 
+    @test_config("test_diverter_auto_disable.yaml")
     def test_diverter_auto_disable(self):
-        diverter = self.machine.diverters.d_test
+        diverter = self.machine.diverters["d_test"]
 
         # enable diverter
         diverter.enable()
@@ -435,16 +490,17 @@ class TestDiverter(MpfTestCase):
         self.assertFalse(diverter.enabled)
         self.assertFalse(diverter.active)
 
+    @test_config("test_activation_switch_and_eject_confirm_switch.yaml")
     def test_activation_switch_and_eject_confirm_switch(self):
-        diverter = self.machine.diverters.d_test_hold_activation_time
+        diverter = self.machine.diverters["d_test_hold_activation_time"]
 
-        self.machine.coils.c_diverter.enable = MagicMock()
-        self.machine.coils.c_diverter.disable = MagicMock()
+        self.machine.coils["c_diverter"].enable = MagicMock()
+        self.machine.coils["c_diverter"].disable = MagicMock()
 
         self.assertFalse(diverter.enabled)
         self.assertFalse(diverter.active)
 
-        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices.test_trough2
+        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices["test_trough2"]
         self.machine.playfield.add_ball()
 
         self.advance_time_and_run(.01)
@@ -455,21 +511,21 @@ class TestDiverter(MpfTestCase):
         self.advance_time_and_run(3)
         self.assertTrue(diverter.enabled)
         self.assertTrue(diverter.active)
-        self.machine.coils.c_diverter.enable.assert_called_once_with()
-        self.machine.coils.c_diverter.enable = MagicMock()
-        assert not self.machine.coils.c_diverter.disable.called
+        self.machine.coils["c_diverter"].enable.assert_called_once_with()
+        self.machine.coils["c_diverter"].enable = MagicMock()
+        assert not self.machine.coils["c_diverter"].disable.called
 
         self.advance_time_and_run(4)
-        self.machine.coils.c_diverter.disable.assert_called_once_with()
-        assert not self.machine.coils.c_diverter.enable.called
+        self.machine.coils["c_diverter"].disable.assert_called_once_with()
+        assert not self.machine.coils["c_diverter"].enable.called
 
         self.hit_and_release_switch("s_playfield")
         self.machine_run()
         self.assertFalse(diverter.active)
 
         self.hit_switch_and_run("s_ball_switch1", 1)
-        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices.test_target
-        self.machine.ball_devices.test_trough2.eject(1, self.machine.ball_devices.test_target)
+        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices["test_target"]
+        self.machine.ball_devices["test_trough2"].eject(1, self.machine.ball_devices["test_target"])
 
         self.advance_time_and_run(.01)
         self.assertFalse(diverter.enabled)
@@ -481,24 +537,25 @@ class TestDiverter(MpfTestCase):
         self.assertFalse(diverter.active)
 
         self.advance_time_and_run(4)
-        assert not self.machine.coils.c_diverter.enable.called
+        assert not self.machine.coils["c_diverter"].enable.called
         self.assertEqual(0, diverter.diverting_ejects_count)
 
+    @test_config("test_diverter_dual_wound_coil.yaml")
     def test_diverter_dual_wound_coil(self):
-        diverter = self.machine.diverters.d_test_dual_wound
+        diverter = self.machine.diverters["d_test_dual_wound"]
 
-        self.assertEqual("idle", self.machine.ball_devices.test_trough._state)
-        self.assertEqual("idle", self.machine.ball_devices.test_target._state)
+        self.assertEqual("idle", self.machine.ball_devices["test_trough"]._state)
+        self.assertEqual("idle", self.machine.ball_devices["test_target"]._state)
 
-        self.machine.coils.c_hold.enable = MagicMock()
-        self.machine.coils.c_hold.disable = MagicMock()
-        self.machine.coils.c_power.pulse = MagicMock()
+        self.machine.coils["c_hold"].enable = MagicMock()
+        self.machine.coils["c_hold"].disable = MagicMock()
+        self.machine.coils["c_power"].pulse = MagicMock()
 
         self.assertFalse(diverter.enabled)
         self.assertFalse(diverter.active)
 
         # test active side
-        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices.test_trough
+        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices["test_trough"]
         self.machine.playfield.add_ball()
 
         self.advance_time_and_run(1)
@@ -509,23 +566,23 @@ class TestDiverter(MpfTestCase):
         self.advance_time_and_run(0.5)
         self.assertTrue(diverter.enabled)
         self.assertTrue(diverter.active)
-        self.machine.coils.c_hold.enable.assert_called_once_with()
-        self.machine.coils.c_hold.enable = MagicMock()
-        self.assertTrue(self.machine.coils.c_power.pulse.called)
-        self.machine.coils.c_power.pulse = MagicMock()
-        assert not self.machine.coils.c_hold.disable.called
+        self.machine.coils["c_hold"].enable.assert_called_once_with()
+        self.machine.coils["c_hold"].enable = MagicMock()
+        self.assertTrue(self.machine.coils["c_power"].pulse.called)
+        self.machine.coils["c_power"].pulse = MagicMock()
+        assert not self.machine.coils["c_hold"].disable.called
 
         self.advance_time_and_run(4)
-        assert not self.machine.coils.c_hold.disable.called
+        assert not self.machine.coils["c_hold"].disable.called
 
         self.hit_and_release_switch("s_playfield")
         self.machine_run()
         self.assertFalse(diverter.active)
-        self.machine.coils.c_hold.disable.assert_called_once_with()
+        self.machine.coils["c_hold"].disable.assert_called_once_with()
 
         self.hit_switch_and_run("s_ball_switch1", 1)
         # test inactive side
-        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices.test_target
+        self.machine.playfield.config['default_source_device'] = self.machine.ball_devices["test_target"]
         self.machine.playfield.add_ball()
 
         self.advance_time_and_run(3)
@@ -538,7 +595,7 @@ class TestDiverter(MpfTestCase):
         self.assertFalse(diverter.active)
 
         self.advance_time_and_run(4)
-        assert not self.machine.coils.c_hold.enable.called
-        assert not self.machine.coils.c_power.pulse.called
+        assert not self.machine.coils["c_hold"].enable.called
+        assert not self.machine.coils["c_power"].pulse.called
 
         self.hit_switch_and_run("s_ball_switch1", 1)

pip install -e .
parse_log_pytest
pytest
pytest
apt-get update apt-get install -y gcc pip install -U pip setuptools pip install Cython==0.24.1
3.6
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
asciimatics==1.14.0
attrs @ file:///opt/conda/conda-bld/attrs_1642510447205/work
certifi==2021.5.30
Cython==0.24.1
future==1.0.0
importlib-metadata @ file:///tmp/build/80754af9/importlib-metadata_1631916693255/work
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
more-itertools @ file:///tmp/build/80754af9/more-itertools_1637733554872/work
-e git+https://github.com/missionpinball/mpf.git@fae71087b212c35ffa32a7a9da82afe8fe9eb544#egg=mpf
packaging @ file:///tmp/build/80754af9/packaging_1637314298585/work
Pillow==8.4.0
pluggy @ file:///tmp/build/80754af9/pluggy_1615976315926/work
psutil==7.0.0
py @ file:///opt/conda/conda-bld/py_1644396412707/work
pyfiglet==0.8.post1
pyparsing @ file:///tmp/build/80754af9/pyparsing_1635766073266/work
pyserial==3.5
pyserial-asyncio==0.6
pytest==6.2.4
ruamel.yaml==0.15.37
sortedcontainers==2.4.0
terminaltables==3.1.10
toml @ file:///tmp/build/80754af9/toml_1616166611790/work
typing==3.7.4.3
typing_extensions @ file:///opt/conda/conda-bld/typing_extensions_1647553014482/work
wcwidth==0.2.13
zipp @ file:///tmp/build/80754af9/zipp_1633618647012/work

name: mpf
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - attrs=21.4.0=pyhd3eb1b0_0
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - importlib-metadata=4.8.1=py36h06a4308_0
  - importlib_metadata=4.8.1=hd3eb1b0_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - more-itertools=8.12.0=pyhd3eb1b0_0
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - packaging=21.3=pyhd3eb1b0_0
  - pluggy=0.13.1=py36h06a4308_0
  - py=1.11.0=pyhd3eb1b0_0
  - pyparsing=3.0.4=pyhd3eb1b0_0
  - pytest=6.2.4=py36h06a4308_2
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - toml=0.10.2=pyhd3eb1b0_0
  - typing_extensions=4.1.1=pyh06a4308_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zipp=3.6.0=pyhd3eb1b0_0
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - asciimatics==1.14.0
      - cython==0.24.1
      - future==1.0.0
      - pillow==8.4.0
      - pip==21.3.1
      - psutil==7.0.0
      - pyfiglet==0.8.post1
      - pyserial==3.5
      - pyserial-asyncio==0.6
      - ruamel-yaml==0.15.37
      - setuptools==59.6.0
      - sortedcontainers==2.4.0
      - terminaltables==3.1.10
      - typing==3.7.4.3
      - wcwidth==0.2.13
prefix: /opt/conda/envs/mpf

mpf/tests/test_Diverter.py::TestDiverter::test_diverter_with_servo_and_stepper
mpf/tests/test_Diverter.py::TestDiverter::test_activation_switch_and_eject_confirm_switch mpf/tests/test_Diverter.py::TestDiverter::test_delayed_eject mpf/tests/test_Diverter.py::TestDiverter::test_diverter_auto_disable mpf/tests/test_Diverter.py::TestDiverter::test_diverter_dual_wound_coil mpf/tests/test_Diverter.py::TestDiverter::test_diverter_with_switch mpf/tests/test_Diverter.py::TestDiverter::test_eject_to_oposide_sides mpf/tests/test_Diverter.py::TestDiverter::test_eject_to_oposide_sides2 mpf/tests/test_Diverter.py::TestDiverter::test_hold_activation_time mpf/tests/test_Diverter.py::TestDiverter::test_hold_no_activation_time mpf/tests/test_Diverter.py::TestDiverter::test_missing_ball_at_source mpf/tests/test_Diverter.py::TestDiverter::test_pulsed_activation_time
mpf/devices/diverter.py mpf/devices/stepper.py mpf/core/machine.py
mpf/devices/diverter.py mpf/devices/stepper.py mpf/core/machine.py