async def test_sensor_dark(hass): """Test that darkness (no comms) is handled correctly.""" mock_entry = _mock_config_entry() utcnow = dt_util.utcnow() # sun is up with patch("aurorapy.client.AuroraSerialClient.connect", return_value=None), patch( "aurorapy.client.AuroraSerialClient.measure", side_effect=_simulated_returns), patch( "aurorapy.client.AuroraSerialClient.serial_number", return_value="9876543", ), patch( "aurorapy.client.AuroraSerialClient.version", return_value="9.8.7.6", ), patch( "aurorapy.client.AuroraSerialClient.pn", return_value="A.B.C", ), patch( "aurorapy.client.AuroraSerialClient.firmware", return_value="1.234", ): mock_entry.add_to_hass(hass) await hass.config_entries.async_setup(mock_entry.entry_id) await hass.async_block_till_done() power = hass.states.get("sensor.power_output") assert power is not None assert power.state == "45.7" # sunset with patch("aurorapy.client.AuroraSerialClient.connect", return_value=None), patch( "aurorapy.client.AuroraSerialClient.measure", side_effect=AuroraError("No response after 10 seconds"), ): async_fire_time_changed(hass, utcnow + timedelta(seconds=60)) await hass.async_block_till_done() power = hass.states.get("sensor.power_output") assert power.state == "unknown" # sun rose again with patch("aurorapy.client.AuroraSerialClient.connect", return_value=None), patch( "aurorapy.client.AuroraSerialClient.measure", side_effect=_simulated_returns): async_fire_time_changed(hass, utcnow + timedelta(seconds=60)) await hass.async_block_till_done() power = hass.states.get("sensor.power_output") assert power is not None assert power.state == "45.7" # sunset with patch("aurorapy.client.AuroraSerialClient.connect", return_value=None), patch( "aurorapy.client.AuroraSerialClient.measure", side_effect=AuroraError("No response after 10 seconds"), ): async_fire_time_changed(hass, utcnow + timedelta(seconds=60)) await hass.async_block_till_done() power = hass.states.get("sensor.power_output") assert power.state == "unknown" # should this be 'available'?
async def test_import_night(hass): """Test .yaml import when the inverter is inaccessible (e.g. darkness).""" # First time round, no response. with patch( "aurorapy.client.AuroraSerialClient.connect", side_effect=AuroraError("No response after"), ) as mock_connect: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=TEST_DATA) configs = hass.config_entries.async_entries(DOMAIN) assert len(configs) == 1 entry = configs[0] assert not entry.unique_id assert entry.state == ConfigEntryState.SETUP_RETRY assert len(mock_connect.mock_calls) == 1 assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY assert result["data"][CONF_PORT] == "/dev/ttyUSB7" assert result["data"][CONF_ADDRESS] == 3 # Second time round, talking this time. with patch( "aurorapy.client.AuroraSerialClient.connect", return_value=None, ), patch( "aurorapy.client.AuroraSerialClient.serial_number", return_value="9876543", ), patch( "aurorapy.client.AuroraSerialClient.version", return_value="9.8.7.6", ), patch( "aurorapy.client.AuroraSerialClient.pn", return_value="A.B.C", ), patch( "aurorapy.client.AuroraSerialClient.firmware", return_value="1.234", ), patch( "aurorapy.client.AuroraSerialClient.measure", side_effect=_simulated_returns, ): # Wait >5seconds for the config to auto retry. async_fire_time_changed(hass, utcnow() + timedelta(seconds=6)) await hass.async_block_till_done() assert entry.state == ConfigEntryState.LOADED assert entry.unique_id assert len(mock_connect.mock_calls) == 1 power = hass.states.get("sensor.power_output") assert power assert power.state == "45.7" assert len(hass.config_entries.async_entries(DOMAIN)) == 1
async def test_sensor_unknown_error(hass): """Test other comms error is handled correctly.""" mock_entry = _mock_config_entry() with patch("aurorapy.client.AuroraSerialClient.connect", return_value=None), patch( "aurorapy.client.AuroraSerialClient.measure", side_effect=AuroraError("another error"), ): mock_entry.add_to_hass(hass) await hass.config_entries.async_setup(mock_entry.entry_id) await hass.async_block_till_done() power = hass.states.get("sensor.power_output") assert power is None
async def test_import_com_port_wont_open(hass): """Test we display correct info when comport won't open.""" with patch( "aurorapy.client.AuroraSerialClient.connect", side_effect=AuroraError("..could not open port..."), ): await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=TEST_DATA) configs = hass.config_entries.async_entries(DOMAIN) assert len(configs) == 1 entry = configs[0] assert entry.state == ConfigEntryState.SETUP_ERROR
async def test_form_invalid_com_ports(hass): """Test we display correct info when the comport is invalid..""" fakecomports = [] fakecomports.append(list_ports_common.ListPortInfo("/dev/ttyUSB7")) with patch( "serial.tools.list_ports.comports", return_value=fakecomports, ): result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER}) assert result["type"] == "form" assert result["errors"] == {} with patch( "aurorapy.client.AuroraSerialClient.connect", side_effect=OSError(19, "...no such device..."), return_value=None, ): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], { CONF_PORT: "/dev/ttyUSB7", CONF_ADDRESS: 7 }, ) assert result2["errors"] == {"base": "invalid_serial_port"} with patch( "aurorapy.client.AuroraSerialClient.connect", side_effect=AuroraError("..could not open port..."), return_value=None, ): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], { CONF_PORT: "/dev/ttyUSB7", CONF_ADDRESS: 7 }, ) assert result2["errors"] == {"base": "cannot_open_serial_port"} with patch( "aurorapy.client.AuroraSerialClient.connect", side_effect=AuroraTimeoutError("...No response after..."), return_value=None, ): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], { CONF_PORT: "/dev/ttyUSB7", CONF_ADDRESS: 7 }, ) assert result2["errors"] == {"base": "cannot_connect"} with patch( "aurorapy.client.AuroraSerialClient.connect", side_effect=AuroraError("...Some other message!!!123..."), return_value=None, ), patch( "serial.Serial.isOpen", return_value=True, ), patch("aurorapy.client.AuroraSerialClient.close", ) as mock_clientclose: result2 = await hass.config_entries.flow.async_configure( result["flow_id"], { CONF_PORT: "/dev/ttyUSB7", CONF_ADDRESS: 7 }, ) assert result2["errors"] == {"base": "cannot_connect"} assert len(mock_clientclose.mock_calls) == 1
async def test_import_night_then_user(hass): """Attempt yaml import and fail (dark), but user sets up manually before auto retry.""" TEST_DATA = {"device": "/dev/ttyUSB7", "address": 3, "name": "MyAuroraPV"} # First time round, no response. with patch( "aurorapy.client.AuroraSerialClient.connect", side_effect=AuroraError("No response after"), ) as mock_connect: result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=TEST_DATA) configs = hass.config_entries.async_entries(DOMAIN) assert len(configs) == 1 entry = configs[0] assert not entry.unique_id assert entry.state == ConfigEntryState.SETUP_RETRY assert len(mock_connect.mock_calls) == 1 assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY assert result["data"][CONF_PORT] == "/dev/ttyUSB7" assert result["data"][CONF_ADDRESS] == 3 # Failed once, now simulate the user initiating config flow with valid settings. fakecomports = [] fakecomports.append(list_ports_common.ListPortInfo("/dev/ttyUSB7")) with patch( "serial.tools.list_ports.comports", return_value=fakecomports, ): result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER}) assert result["type"] == "form" assert result["errors"] == {} with patch( "aurorapy.client.AuroraSerialClient.connect", return_value=None, ), patch( "aurorapy.client.AuroraSerialClient.serial_number", return_value="9876543", ), patch( "aurorapy.client.AuroraSerialClient.version", return_value="9.8.7.6", ), patch( "aurorapy.client.AuroraSerialClient.pn", return_value="A.B.C", ), patch( "aurorapy.client.AuroraSerialClient.firmware", return_value="1.234", ): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], { CONF_PORT: "/dev/ttyUSB7", CONF_ADDRESS: 7 }, ) assert result2["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY assert len(hass.config_entries.async_entries(DOMAIN)) == 2 # Now retry yaml - it should fail with duplicate with patch( "aurorapy.client.AuroraSerialClient.connect", return_value=None, ), patch( "aurorapy.client.AuroraSerialClient.serial_number", return_value="9876543", ), patch( "aurorapy.client.AuroraSerialClient.version", return_value="9.8.7.6", ), patch( "aurorapy.client.AuroraSerialClient.pn", return_value="A.B.C", ), patch( "aurorapy.client.AuroraSerialClient.firmware", return_value="1.234", ): # Wait >5seconds for the config to auto retry. async_fire_time_changed(hass, utcnow() + timedelta(seconds=6)) await hass.async_block_till_done() assert entry.state == ConfigEntryState.NOT_LOADED assert len(hass.config_entries.async_entries(DOMAIN)) == 1