We're getting there! I pumped up the eject_timeouts: and ball_missing_timeouts: times and haven't had an issue with the trough trying to kick when the ball is already in play.
The next thing to address is that when the ball drains after completing the Wizard sequence, the ball doesn't advance and a new ball doesn't kick out. I highlighted the differences between pre-Wizard and Post-Wizard drains and discovered that "ball_ending" posts but not "ball_ended" and "player_turn_stop" fails to post at all (which leads to a whole long "new ball" sequence). What could be preventing that and how do I adjust for it?
Here's what a pre-wizard drain looks like:
SwitchController : <<<<<<< 's_switch4' active >>>>>>>
SwitchController : Found timed switch handler for k/v 2256.916988549 / {'return_info': False, 'ms': 2000, 'removed': False, 'callback': <bound method SwitchCounter._switch_changed of <mpf.devices.ball_device.switch_counter.SwitchCounter object at 0x104718be0>>, 'switch_action': 's_switch4-1', 'state': 1, 'callback_kwargs': {}, 'switch_name': 's_switch4'}
EventManager : Event: ======'s_switch4_active'====== Args={}
SwitchController : WARNING: Received duplicate switch state, which means this switch had some non-debounced state changes. This could be nothing, but if it happens a lot it could indicate noise or interference on the line. Switch: s_switch4
SwitchController : Processing timed switch handler. Switch: s_switch4 State: 1, ms: 2000
ball_device.bd_trough : Counted 1 balls. Active switches: ['s_switch4']
ball_device.bd_trough : Counting idle
ball_device.bd_trough : BCH: Found 1 new balls
ball_device.bd_trough : Received unexpected ball
EventManager : Event: ======'balldevice_captured_from_playfield'====== Args={'balls': 1}
EventManager : Event: ======'sw_playfield_active'====== Args={'balls': 1}
EventManager : Event: ======'playfield_ball_count_change'====== Args={'change': -1, 'balls': 0}
ball_device.bd_trough : Counted 1 balls. Active switches: ['s_switch4']
ball_device.bd_trough : Processing new ball
EventManager : Event: ======'balldevice_bd_trough_ball_enter'====== Args={'device': <ball_device.bd_trough>, 'unclaimed_balls': 1, 'new_balls': 1}
EventManager : Event: ======'ball_drain'====== Args={'device': <ball_device.bd_trough>, 'balls': 1}
EventManager : Event: ======'ball_will_end'====== Args={}
EventManager : Event: ======'ball_ending'====== Args={}
EventManager : Event: ======'ball_ended'====== Args={}
ball_device.bd_trough : Adding ball
EventManager : Event: ======'balldevice_balls_available'====== Args={}
EventManager : Event: ======'balldevice_bd_trough_ball_entered'====== Args={'device': <ball_device.bd_trough>, 'new_balls': 1}
EventManager : Event: ======'player_turn_stop'====== Args={'player': <Player 1>, 'number': 1}
EventManager : Event: ======'player_turn_start'====== Args={'player': <Player 1>, 'number': 1}
EventManager : Event: ======'player_turn_starting'====== Args={'player': <Player 1>, 'number': 1}
EventManager : Event: ======'player_ball'====== Args={'change': 1, 'player_num': 1, 'value': 2, 'prev_value': 1}
EventManager : Event: ======'player_turn_started'====== Args={'player': <Player 1>, 'number': 1}
EventManager : Event: ======'ball_starting'====== Args={'is_extra_ball': False, 'balls_remaining': 1}
EventManager : Event: ======'balls_in_play'====== Args={'balls': 1}
EventManager : Event: ======'ball_started'====== Args={'player': 1, 'ball': 2}
EventManager : Event: ======'single_player_ball_started'====== Args={}
ball_device.bd_trough : Setting up player-controlled eject. Balls: 1, Target: <playfield.playfield>, player_controlled_eject_event: None
ball_device.bd_trough : Adding 1 ball(s) to the eject_queue with target <playfield.playfield>.
ball_device.bd_trough : Adding eject chain
EventManager : Event: ======'balldevice_balls_available'====== Args={}
ball_device.bd_trough : Got eject request
EventManager : Event: ======'balldevice_bd_trough_ball_eject_attempt'====== Args={'mechanical_eject': False, 'num_attempts': 0, 'target': <playfield.playfield>, 'source': <ball_device.bd_trough>, 'balls': 1}
ball_device.bd_trough : Ejecting ball to <playfield.playfield>
EventManager : Event: ======'balldevice_bd_trough_ejecting_ball'====== Args={'mechanical_eject': False, 'num_attempts': 0, 'target': <playfield.playfield>, 'source': <ball_device.bd_trough>, 'balls': 1}
ball_device.bd_trough : Entered eject mode.
SwitchController : Registering switch handler: s_switch4, functools.partial(<function SwitchController._wait_handler at 0x10399aea0>, ms=0, _future=<Future pending cb=[SwitchController._future_done([])()]>, switch_name='s_switch4'), state: 0, ms: 0, info: False, cb_kwargs: {}
ball_device.bd_trough : Counted 1 balls. Active switches: ['s_switch4']
ball_device.bd_trough : Waiting for eject to end
ball_device.bd_trough : Wait for ball to leave device
ball_device.bd_trough : Firing eject coil. Current balls: 1.
SwitchController : <<<<<<< 's_switch4' inactive >>>>>>>
SwitchController : Found timed switch handler for k/v 2257.509407724 / {'return_info': False, 'ms': 500, 'removed': False, 'callback': <bound method SwitchCounter._switch_changed of <mpf.devices.ball_device.switch_counter.SwitchCounter object at 0x104718be0>>, 'switch_action': 's_switch4-0', 'state': 0, 'callback_kwargs': {}, 'switch_name': 's_switch4'}
EventManager : Event: ======'s_switch4_inactive'====== Args={}
SwitchController : Removing switch handler. Switch: s_switch4, State: 0, ms: 0
ball_device.bd_trough : Got ball left during eject
ball_device.bd_trough : Switch 's_switch4' changed too recently. Aborting count!
ball_device.bd_trough : Ball left
ball_device.bd_trough : Wait for confirm with timeout 29.0
SwitchController : Processing timed switch handler. Switch: s_switch4 State: 0, ms: 500
ball_device.bd_trough : Counted 0 balls. Active switches: []
EventManager : Event: ======'restore'====== Args={}
EventManager : Event: ======'drop_target_bank_five_drop_reset_lower_up'====== Args={}
EventManager : Event: ======'restore'====== Args={}
EventManager : Event: ======'drop_target_bank_five_drop_reset_upper_up'====== Args={}
EventManager : Event: ======'restore'====== Args={}
EventManager : Event: ======'drop_target_bank_three_drop_reset_up'====== Args={}
and here's what a post-Wizard drain looks like:
SwitchController : <<<<<<< 's_switch4' active >>>>>>>
SwitchController : Found timed switch handler for k/v 1930.042713698 / {'switch_action': 's_switch4-1', 'removed': False, 'switch_name': 's_switch4', 'callback': <bound method SwitchCounter._switch_changed of <mpf.devices.ball_device.switch_counter.SwitchCounter object at 0x104712e80>>, 'ms': 2000, 'state': 1, 'callback_kwargs': {}, 'return_info': False}
EventManager : Event: ======'s_switch4_active'====== Args={}
SwitchController : WARNING: Received duplicate switch state, which means this switch had some non-debounced state changes. This could be nothing, but if it happens a lot it could indicate noise or interference on the line. Switch: s_switch4
SwitchController : WARNING: Received duplicate switch state, which means this switch had some non-debounced state changes. This could be nothing, but if it happens a lot it could indicate noise or interference on the line. Switch: s_switch4
SwitchController : Processing timed switch handler. Switch: s_switch4 State: 1, ms: 2000
ball_device.bd_trough : Counted 1 balls. Active switches: ['s_switch4']
ball_device.bd_trough : Counting idle
ball_device.bd_trough : BCH: Found 1 new balls
ball_device.bd_trough : Received unexpected ball
EventManager : Event: ======'balldevice_captured_from_playfield'====== Args={'balls': 1}
EventManager : Event: ======'sw_playfield_active'====== Args={'balls': 1}
EventManager : Event: ======'playfield_ball_count_change'====== Args={'balls': 0, 'change': -1}
ball_device.bd_trough : Counted 1 balls. Active switches: ['s_switch4']
ball_device.bd_trough : Processing new ball
EventManager : Event: ======'balldevice_bd_trough_ball_enter'====== Args={'new_balls': 1, 'device': <ball_device.bd_trough>, 'unclaimed_balls': 1}
EventManager : Event: ======'ball_drain'====== Args={'balls': 1, 'device': <ball_device.bd_trough>}
EventManager : Event: ======'ball_will_end'====== Args={}
EventManager : Event: ======'ball_ending'====== Args={}
ball_device.bd_trough : Adding ball
EventManager : Event: ======'balldevice_balls_available'====== Args={}
EventManager : Event: ======'balldevice_bd_trough_ball_entered'====== Args={'new_balls': 1, 'device': <ball_device.bd_trough>}