Add error sensor for Husqvarna Automower (#113165)

* Add error sensor for Husqvarna Automower

* Apply suggestions from code review

Co-authored-by: Jan-Philipp Benecke <github@bnck.me>

* address review

* Add restricted reason sensor

* ruff

* pin options

---------

Co-authored-by: Jan-Philipp Benecke <github@bnck.me>
This commit is contained in:
Thomas55555
2024-03-31 20:06:30 +02:00
committed by GitHub
co-authored by Jan-Philipp Benecke
parent 7919ca63d0
commit 5eb4cf6a05
5 changed files with 760 additions and 1 deletions
@@ -104,6 +104,344 @@
'state': '0.034',
})
# ---
# name: test_sensor[sensor.test_mower_1_error-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'options': list([
'no_error',
'alarm_mower_in_motion',
'alarm_mower_lifted',
'alarm_mower_stopped',
'alarm_mower_switched_off',
'alarm_mower_tilted',
'alarm_outside_geofence',
'angular_sensor_problem',
'battery_problem',
'battery_problem',
'battery_restriction_due_to_ambient_temperature',
'can_error',
'charging_current_too_high',
'charging_station_blocked',
'charging_system_problem',
'charging_system_problem',
'collision_sensor_defect',
'collision_sensor_error',
'collision_sensor_problem_front',
'collision_sensor_problem_rear',
'com_board_not_available',
'communication_circuit_board_sw_must_be_updated',
'complex_working_area',
'connection_changed',
'connection_not_changed',
'connectivity_problem',
'connectivity_problem',
'connectivity_problem',
'connectivity_problem',
'connectivity_problem',
'connectivity_problem',
'connectivity_settings_restored',
'cutting_drive_motor_1_defect',
'cutting_drive_motor_2_defect',
'cutting_drive_motor_3_defect',
'cutting_height_blocked',
'cutting_height_problem',
'cutting_height_problem_curr',
'cutting_height_problem_dir',
'cutting_height_problem_drive',
'cutting_motor_problem',
'cutting_stopped_slope_too_steep',
'cutting_system_blocked',
'cutting_system_blocked',
'cutting_system_imbalance_warning',
'cutting_system_major_imbalance',
'destination_not_reachable',
'difficult_finding_home',
'docking_sensor_defect',
'electronic_problem',
'empty_battery',
'folding_cutting_deck_sensor_defect',
'folding_sensor_activated',
'geofence_problem',
'geofence_problem',
'gps_navigation_problem',
'guide_1_not_found',
'guide_2_not_found',
'guide_3_not_found',
'guide_calibration_accomplished',
'guide_calibration_failed',
'high_charging_power_loss',
'high_internal_power_loss',
'high_internal_temperature',
'internal_voltage_error',
'invalid_battery_combination_invalid_combination_of_different_battery_types',
'invalid_sub_device_combination',
'invalid_system_configuration',
'left_brush_motor_overloaded',
'lift_sensor_defect',
'lifted',
'limited_cutting_height_range',
'limited_cutting_height_range',
'loop_sensor_defect',
'loop_sensor_problem_front',
'loop_sensor_problem_left',
'loop_sensor_problem_rear',
'loop_sensor_problem_right',
'low_battery',
'memory_circuit_problem',
'mower_lifted',
'mower_tilted',
'no_accurate_position_from_satellites',
'no_confirmed_position',
'no_drive',
'no_loop_signal',
'no_power_in_charging_station',
'no_response_from_charger',
'outside_working_area',
'poor_signal_quality',
'reference_station_communication_problem',
'right_brush_motor_overloaded',
'safety_function_faulty',
'settings_restored',
'sim_card_locked',
'sim_card_locked',
'sim_card_locked',
'sim_card_locked',
'sim_card_not_found',
'sim_card_requires_pin',
'slipped_mower_has_slipped_situation_not_solved_with_moving_pattern',
'slope_too_steep',
'sms_could_not_be_sent',
'stop_button_problem',
'stuck_in_charging_station',
'switch_cord_problem',
'temporary_battery_problem',
'temporary_battery_problem',
'temporary_battery_problem',
'temporary_battery_problem',
'temporary_battery_problem',
'temporary_battery_problem',
'temporary_battery_problem',
'temporary_battery_problem',
'tilt_sensor_problem',
'too_high_discharge_current',
'too_high_internal_current',
'trapped',
'ultrasonic_problem',
'ultrasonic_sensor_1_defect',
'ultrasonic_sensor_2_defect',
'ultrasonic_sensor_3_defect',
'ultrasonic_sensor_4_defect',
'unexpected_cutting_height_adj',
'unexpected_error',
'upside_down',
'weak_gps_signal',
'wheel_drive_problem_left',
'wheel_drive_problem_rear_left',
'wheel_drive_problem_rear_right',
'wheel_drive_problem_right',
'wheel_motor_blocked_left',
'wheel_motor_blocked_rear_left',
'wheel_motor_blocked_rear_right',
'wheel_motor_blocked_right',
'wheel_motor_overloaded_left',
'wheel_motor_overloaded_rear_left',
'wheel_motor_overloaded_rear_right',
'wheel_motor_overloaded_right',
'work_area_not_valid',
'wrong_loop_signal',
'wrong_pin_code',
'zone_generator_problem',
]),
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_mower_1_error',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
'original_icon': None,
'original_name': 'Error',
'platform': 'husqvarna_automower',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'error',
'unique_id': 'c7233734-b219-4287-a173-08e3643f89f0_error',
'unit_of_measurement': None,
})
# ---
# name: test_sensor[sensor.test_mower_1_error-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'enum',
'friendly_name': 'Test Mower 1 Error',
'options': list([
'no_error',
'alarm_mower_in_motion',
'alarm_mower_lifted',
'alarm_mower_stopped',
'alarm_mower_switched_off',
'alarm_mower_tilted',
'alarm_outside_geofence',
'angular_sensor_problem',
'battery_problem',
'battery_problem',
'battery_restriction_due_to_ambient_temperature',
'can_error',
'charging_current_too_high',
'charging_station_blocked',
'charging_system_problem',
'charging_system_problem',
'collision_sensor_defect',
'collision_sensor_error',
'collision_sensor_problem_front',
'collision_sensor_problem_rear',
'com_board_not_available',
'communication_circuit_board_sw_must_be_updated',
'complex_working_area',
'connection_changed',
'connection_not_changed',
'connectivity_problem',
'connectivity_problem',
'connectivity_problem',
'connectivity_problem',
'connectivity_problem',
'connectivity_problem',
'connectivity_settings_restored',
'cutting_drive_motor_1_defect',
'cutting_drive_motor_2_defect',
'cutting_drive_motor_3_defect',
'cutting_height_blocked',
'cutting_height_problem',
'cutting_height_problem_curr',
'cutting_height_problem_dir',
'cutting_height_problem_drive',
'cutting_motor_problem',
'cutting_stopped_slope_too_steep',
'cutting_system_blocked',
'cutting_system_blocked',
'cutting_system_imbalance_warning',
'cutting_system_major_imbalance',
'destination_not_reachable',
'difficult_finding_home',
'docking_sensor_defect',
'electronic_problem',
'empty_battery',
'folding_cutting_deck_sensor_defect',
'folding_sensor_activated',
'geofence_problem',
'geofence_problem',
'gps_navigation_problem',
'guide_1_not_found',
'guide_2_not_found',
'guide_3_not_found',
'guide_calibration_accomplished',
'guide_calibration_failed',
'high_charging_power_loss',
'high_internal_power_loss',
'high_internal_temperature',
'internal_voltage_error',
'invalid_battery_combination_invalid_combination_of_different_battery_types',
'invalid_sub_device_combination',
'invalid_system_configuration',
'left_brush_motor_overloaded',
'lift_sensor_defect',
'lifted',
'limited_cutting_height_range',
'limited_cutting_height_range',
'loop_sensor_defect',
'loop_sensor_problem_front',
'loop_sensor_problem_left',
'loop_sensor_problem_rear',
'loop_sensor_problem_right',
'low_battery',
'memory_circuit_problem',
'mower_lifted',
'mower_tilted',
'no_accurate_position_from_satellites',
'no_confirmed_position',
'no_drive',
'no_loop_signal',
'no_power_in_charging_station',
'no_response_from_charger',
'outside_working_area',
'poor_signal_quality',
'reference_station_communication_problem',
'right_brush_motor_overloaded',
'safety_function_faulty',
'settings_restored',
'sim_card_locked',
'sim_card_locked',
'sim_card_locked',
'sim_card_locked',
'sim_card_not_found',
'sim_card_requires_pin',
'slipped_mower_has_slipped_situation_not_solved_with_moving_pattern',
'slope_too_steep',
'sms_could_not_be_sent',
'stop_button_problem',
'stuck_in_charging_station',
'switch_cord_problem',
'temporary_battery_problem',
'temporary_battery_problem',
'temporary_battery_problem',
'temporary_battery_problem',
'temporary_battery_problem',
'temporary_battery_problem',
'temporary_battery_problem',
'temporary_battery_problem',
'tilt_sensor_problem',
'too_high_discharge_current',
'too_high_internal_current',
'trapped',
'ultrasonic_problem',
'ultrasonic_sensor_1_defect',
'ultrasonic_sensor_2_defect',
'ultrasonic_sensor_3_defect',
'ultrasonic_sensor_4_defect',
'unexpected_cutting_height_adj',
'unexpected_error',
'upside_down',
'weak_gps_signal',
'wheel_drive_problem_left',
'wheel_drive_problem_rear_left',
'wheel_drive_problem_rear_right',
'wheel_drive_problem_right',
'wheel_motor_blocked_left',
'wheel_motor_blocked_rear_left',
'wheel_motor_blocked_rear_right',
'wheel_motor_blocked_right',
'wheel_motor_overloaded_left',
'wheel_motor_overloaded_rear_left',
'wheel_motor_overloaded_rear_right',
'wheel_motor_overloaded_right',
'work_area_not_valid',
'wrong_loop_signal',
'wrong_pin_code',
'zone_generator_problem',
]),
}),
'context': <ANY>,
'entity_id': 'sensor.test_mower_1_error',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'no_error',
})
# ---
# name: test_sensor[sensor.test_mower_1_mode-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
@@ -311,6 +649,78 @@
'state': '11396',
})
# ---
# name: test_sensor[sensor.test_mower_1_restricted_reason-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'options': list([
'all_work_areas_completed',
'daily_limit',
'external',
'fota',
'frost',
'none',
'not_applicable',
'park_override',
'sensor',
'week_schedule',
]),
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_mower_1_restricted_reason',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
'original_icon': None,
'original_name': 'Restricted reason',
'platform': 'husqvarna_automower',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'restricted_reason',
'unique_id': 'c7233734-b219-4287-a173-08e3643f89f0_restricted_reason',
'unit_of_measurement': None,
})
# ---
# name: test_sensor[sensor.test_mower_1_restricted_reason-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'enum',
'friendly_name': 'Test Mower 1 Restricted reason',
'options': list([
'all_work_areas_completed',
'daily_limit',
'external',
'fota',
'frost',
'none',
'not_applicable',
'park_override',
'sensor',
'week_schedule',
]),
}),
'context': <ANY>,
'entity_id': 'sensor.test_mower_1_restricted_reason',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'week_schedule',
})
# ---
# name: test_sensor[sensor.test_mower_1_total_charging_time-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
@@ -94,6 +94,31 @@ async def test_statistics_not_available(
assert state is None
async def test_error_sensor(
hass: HomeAssistant,
mock_automower_client: AsyncMock,
mock_config_entry: MockConfigEntry,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test error sensor."""
values = mower_list_to_dictionary_dataclass(
load_json_value_fixture("mower.json", DOMAIN)
)
await setup_integration(hass, mock_config_entry)
for state, expected_state in [
(None, "no_error"),
("can_error", "can_error"),
]:
values[TEST_MOWER_ID].mower.error_key = state
mock_automower_client.get_status.return_value = values
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
state = hass.states.get("sensor.test_mower_1_error")
assert state.state == expected_state
async def test_sensor(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,