Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Catch duplicate API key specified (plus scope creep) #226

Open
wants to merge 96 commits into
base: main
Choose a base branch
from

Conversation

autoSteve
Copy link
Collaborator

Why anyone of sound mind would do this is beyond me. But it does result in exceptions that want heading off at the pass...

@autoSteve autoSteve requested a review from BJReplay December 5, 2024 08:56
Copy link
Owner

@BJReplay BJReplay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most polite. No "WTAF?".

@autoSteve
Copy link
Collaborator Author

🤣🤣🤣

@autoSteve
Copy link
Collaborator Author

Long may the changes in the last two PRs hide dormant. Prepped for next anyways.

@BJReplay
Copy link
Owner

BJReplay commented Dec 5, 2024

Long may the changes in the last two PRs hide dormant. Prepped for next anyways.

While I was reviewing and approving your PR, I was sitting in the Palais waiting for...

20241205_220716 1

@autoSteve
Copy link
Collaborator Author

Here's an example for you of how smart Copilot can be.

Scenario: I've copied a unit test function for invalid API limit, and am modifying it to test for invalid hard limit.
Result: The clever bugger has worked out exactly what I am doing and is suggesting absolutely correct lines of code (in grey italic, just press tab...)

image

@autoSteve
Copy link
Collaborator Author

autoSteve commented Dec 6, 2024

We now meet (well, far exceed) the minimum requirements for becoming a core component. Unit testing of config_flow.py is must-ride.

I worked out how to shoehorn pytests for a custom into the dev container environment, with minimal alterations required when transitioned as a core component...

In devcontainer.json...

  "mounts": [
    "source=${localEnv:HOME}/Documents/GitHub/ha-solcast-solar/custom_components/solcast_solar,target=${containerWorkspaceFolder}/config/custom_components/solcast_solar,type=bind",
    "source=${localEnv:HOME}/Documents/GitHub/ha-solcast-solar/tests,target=${containerWorkspaceFolder}/tests/components/solcast_solar,type=bind",

from tests/components/solcast_solar run pytest.

(ha-venv) vscode ➜ /workspaces/…/tests/components/solcast_solar $ pytest
Test session starts (platform: linux, Python 3.12.7, pytest 8.3.3, pytest-sugar 1.0.0)
rootdir: /workspaces/homeAssistant-core
configfile: pyproject.toml
plugins: github-actions-annotate-failures-0.2.0, sugar-1.0.0, pytest_freezer-0.4.8, cov-5.0.0, syrupy-4.7.1, picked-0.5.0, timeout-2.3.1, socket-0.7.0, respx-0.21.1, aiohttp-1.0.5, xdist-3.6.1, asyncio-0.24.0, requests-mock-1.12.1, unordered-0.6.1, anyio-4.6.0
asyncio: mode=Mode.AUTO, default_loop_scope=function
collected 7 items                                                                                                                                                                                                                                                                        

 tests/components/solcast_solar/test_config_flow.py ✓✓✓✓✓✓✓                                                                                                                                                                                                                100% ██████████

Results (0.21s):
       7 passed

@autoSteve autoSteve changed the title Catch duplicate API key specified Catch duplicate API key specified (plus scope creep) Dec 6, 2024
Copy link
Owner

@BJReplay BJReplay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice

@BJReplay
Copy link
Owner

BJReplay commented Dec 6, 2024

We now meet (well, far exceed) the minimum requirements for becoming a core component. Unit testing of config_flow.py is must-ride.

OK, I'll try to have a look over the weekend.

Very tired, now, so off to bed, but maybe we throw it at the wall and see if it sticks.

Will read up on the process.

@autoSteve
Copy link
Collaborator Author

Sounds like a journey, but I'm betting it's a shorter one than HACS at the mo'...

We got this.

@autoSteve
Copy link
Collaborator Author

I've removed the self-signed certs to stop GitGuardian complaining about them. The sim creates the cert if required on startup.

@autoSteve
Copy link
Collaborator Author

The hard limit validation oopsie would have been caught by the unit test had I also looked for an expected positive outcome going wrong instead of expecting the worst from bad input. I did not. The unit test failed everyone.

It sailed through without a care in the world. It does not now.

@autoSteve
Copy link
Collaborator Author

So I am kind-of guessing re. #227. I am only led by the exception.

The latest commit catches the very first exception regarding 'index' and then bluntly refuses to start the integration with an inferance of a corrupt solcast.json file reported. It might prevent issues raised, but more likely will improve sit. rep. and avoid an exploded log with a bunch of knock-on bad stuff happening.

I thought about doing something fancier, but fancier would have required a LOT more input as to the situation, and a LOT more testing. I am not in the mood for testing. And I have no input. So it is what it is for now.

@BJReplay
Copy link
Owner

BJReplay commented Dec 9, 2024

So I am kind-of guessing re. #227.

I am kind-of guessing that some ancient installs - possibly manual, non-HACS, have been upgraded, and they are the cause of the last few issues like this.

@autoSteve
Copy link
Collaborator Author

Kind-of not, I'm tipping.

The log indicated a usage cache load, with a count of two for API used, so must be a relatively recent version. Last reset was within twenty-four hours. This might have been from a prior start attempt, but there are two sites, so if anything API used should be four calls, given history load on fresh start. Unless the second site failed to load...

I got nothin' but conjecture.

2024-12-08 19:54:24.881 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Usage cache exists for ******Zr-mpU
2024-12-08 19:54:24.888 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Usage cache for ******Zr-mpU last reset 2024-12-08 01:00:00
2024-12-08 19:54:24.888 INFO (MainThread) [custom_components.solcast_solar.solcastapi] Usage loaded
2024-12-08 19:54:24.889 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] API counter for ******Zr-mpU is 2/10
2024-12-08 19:54:24.889 DEBUG (MainThread) [custom_components.solcast_solar] UTC times are converted to Europe/Berlin

@BJReplay
Copy link
Owner

BJReplay commented Dec 9, 2024

Kind-of not, I'm tipping.

Ahh, I did squint at the log on my phone after I carefully picked up my specs case, left home, and discovered that I had left me specs at home, but didn't spot that.

@autoSteve
Copy link
Collaborator Author

Further fun with unit tests. test_solcastapi.py.

Just uncovered a bug: Turning off detailed half-hourly attribute with detailed hourly enabled results in a puff of virtual magic smoke.

(ha-venv) vscode ➜ /workspaces/…/tests/components/solcast_solar $ pytest -o log_cli=true --log-cli-level=DEBUG -vv
Test session starts (platform: linux, Python 3.12.7, pytest 8.3.3, pytest-sugar 1.0.0)
cachedir: .pytest_cache
rootdir: /workspaces/homeAssistant-core
configfile: pyproject.toml
plugins: github-actions-annotate-failures-0.2.0, sugar-1.0.0, pytest_freezer-0.4.8, cov-5.0.0, syrupy-4.7.1, picked-0.5.0, timeout-2.3.1, socket-0.7.0, respx-0.21.1, aiohttp-1.0.5, xdist-3.6.1, asyncio-0.24.0, requests-mock-1.12.1, unordered-0.6.1, anyio-4.6.0
asyncio: mode=Mode.AUTO, default_loop_scope=function
collected 16 items                                                                                                                                                                                                                                                                                                         

 tests/components/solcast_solar/test_config_flow.py::test_create_entry ✓                                                                                                                                                                                                                                       6% ▋         
 tests/components/solcast_solar/test_config_flow.py::test_api_key ✓                                                                                                                                                                                                                                           12% █▍        
 tests/components/solcast_solar/test_config_flow.py::test_api_quota ✓                                                                                                                                                                                                                                         19% █▉        
 tests/components/solcast_solar/test_config_flow.py::test_option_api_key ✓                                                                                                                                                                                                                                    25% ██▌       
 tests/components/solcast_solar/test_config_flow.py::test_option_api_quota ✓                                                                                                                                                                                                                                  31% ███▎      
 tests/components/solcast_solar/test_config_flow.py::test_option_custom_hour_sensor ✓                                                                                                                                                                                                                         38% ███▊      
 tests/components/solcast_solar/test_config_flow.py::test_option_hard_limit ✓                                                                                                                                                                                                                                 44% ████▍     
 tests/components/solcast_solar/test_solcastapi.py::test_forecast_update ✓                                                                                                                                                                                                                                    50% █████     
 tests/components/solcast_solar/test_solcastapi.py::test_build_splines ✓                                                                                                                                                                                                                                      56% █████▋    
 tests/components/solcast_solar/test_solcastapi.py::test_get_total_energy_forecast ✓                                                                                                                                                                                                                          62% ██████▍   
 tests/components/solcast_solar/test_solcastapi.py::test_get_peaks ✓                                                                                                                                                                                                                                          69% ██████▉   
 tests/components/solcast_solar/test_solcastapi.py::test_get_power_n_minutes ✓                                                                                                                                                                                                                                75% ███████▌  
 tests/components/solcast_solar/test_solcastapi.py::test_get_forecast_n_hour ✓                                                                                                                                                                                                                                81% ████████▎ 
 tests/components/solcast_solar/test_solcastapi.py::test_get_forecast_custom_hours ✓                                                                                                                                                                                                                          88% ████████▊ 
 tests/components/solcast_solar/test_solcastapi.py::test_get_forecast_remaining_today ✓                                                                                                                                                                                                                       94% █████████▍
 tests/components/solcast_solar/test_solcastapi.py::test_get_forecast_day ✓                                                                                                                                                                                                                                  100% ██████████

Results (0.63s):
      16 passed

@autoSteve
Copy link
Collaborator Author

In this commit is migration of usage.

On key change there should be Using extant cache data for API key ******1 logged, and no reset of usage because key change.

Test coverage still needs work, but there are bloody few lines that miss after all that lot...

Name                                                                                     Stmts   Miss  Cover   Missing
----------------------------------------------------------------------------------------------------------------------
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/__init__.py          358      0   100%
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/config_flow.py       215      0   100%
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/const.py              42      0   100%
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/coordinator.py       266      0   100%
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/diagnostics.py        16      0   100%
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/energy.py             15      0   100%
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/select.py             42      0   100%
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/sensor.py            161      0   100%
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/solcastapi.py       1432      6    99%   554-555, 764, 772-774
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/system_health.py      11      0   100%
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/util.py               94      0   100%
----------------------------------------------------------------------------------------------------------------------
TOTAL                                                                                     2652      6    99%

@autoSteve
Copy link
Collaborator Author

(You could hack together a test for your prod rig by editing solcast-usage.json and upping the used value then restarting. Then change key and watch the benign magic that is lots of changed lines of code.)

@BJReplay
Copy link
Owner

OK, got a slightly odd scenario, here.

  1. Updated code for Prod
  2. Restarted Prod
  3. Updated code for Dev Container
  4. Changed the key on Solcast before starting Dev container (but after restarting Prod) - interested in seeing how it picks up an API change on the fly, so to speak.
  5. Started Dev Container
  6. Did not get Reauth notification or Settings Badge
  7. Did however, get failed setup when I go into integrations in Dev Container Instance

image

image

It looks like the API change is not resulting in a reauth.

Log:

2025-01-20 10:34:10.349 DEBUG (MainThread) [custom_components.solcast_solar] Auto-update options: {'auto_update': 1}
2025-01-20 10:34:10.350 DEBUG (MainThread) [custom_components.solcast_solar] Estimate to use options: {'key_estimate': 'estimate'}
2025-01-20 10:34:10.350 DEBUG (MainThread) [custom_components.solcast_solar] Attribute options: {'attr_brk_detailed': False, 'attr_brk_estimate': True, 'attr_brk_estimate10': True, 'attr_brk_estimate90': True, 'attr_brk_halfhourly': True, 'attr_brk_hourly': True, 'attr_brk_site': True}
2025-01-20 10:34:10.350 DEBUG (MainThread) [custom_components.solcast_solar] Custom sensor options: {'customhoursensor': 1}
2025-01-20 10:34:10.350 DEBUG (MainThread) [custom_components.solcast_solar] Hard limit: {'hard_limit_api': '100.0'}
2025-01-20 10:34:10.520 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Configuration directory is /workspaces/core/config
2025-01-20 10:34:10.520 DEBUG (MainThread) [custom_components.solcast_solar] Session headers: {'Accept': 'application/json', 'User-Agent': 'ha-solcast-solar-integration/4.2'}
2025-01-20 10:34:10.577 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Sites cache exists for ******wxbtdB
2025-01-20 10:34:10.577 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Connecting to https://api.solcast.com.au/rooftop_sites?format=json&api_key=******wxbtdB
2025-01-20 10:34:10.813 WARNING (MainThread) [custom_components.solcast_solar.solcastapi] HTTP session returned status 403/Forbidden, trying cache
2025-01-20 10:34:10.813 WARNING (MainThread) [custom_components.solcast_solar.solcastapi] Get sites failed, last call result: 403/Forbidden, using cached data
2025-01-20 10:34:10.814 INFO (MainThread) [custom_components.solcast_solar.solcastapi] Loading cached sites for ******wxbtdB
2025-01-20 10:34:10.845 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Sites data: {'sites': [{'name': 'BLAH', 'resource_id': 'a546-98c5-53c5-d101', 'capacity': 5, 'capacity_dc': 4.85, 'longitude': **.******, 'latitude': **.******, 'azimuth': -123, 'tilt': 5, 'install_date': '2012-04-18T14:00:00.0000000Z', 'loss_factor': 0.8, 'tags': ['Home', 'St Kilda West', 'Flat Roof', 'Home Assistant'], 'location': 'St Kilda West, VIC Australia', 'api_key': '******wxbtdB'}], 'page_count': 1, 'current_page': 1, 'total_records': 1}
2025-01-20 10:34:10.845 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Sites loaded
2025-01-20 10:34:10.845 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Checking rekey for ******wxbtdB
2025-01-20 10:34:10.845 INFO (MainThread) [custom_components.solcast_solar.solcastapi] API key ******wxbtdB has changed and sites are different invalidating the cache, not loading cached data
2025-01-20 10:34:13.104 DEBUG (MainThread) [custom_components.solcast_solar] Auto-update options: {'auto_update': 1}
2025-01-20 10:34:13.104 DEBUG (MainThread) [custom_components.solcast_solar] Estimate to use options: {'key_estimate': 'estimate'}
2025-01-20 10:34:13.104 DEBUG (MainThread) [custom_components.solcast_solar] Attribute options: {'attr_brk_detailed': False, 'attr_brk_estimate': True, 'attr_brk_estimate10': True, 'attr_brk_estimate90': True, 'attr_brk_halfhourly': True, 'attr_brk_hourly': True, 'attr_brk_site': True}
2025-01-20 10:34:13.104 DEBUG (MainThread) [custom_components.solcast_solar] Custom sensor options: {'customhoursensor': 1}
2025-01-20 10:34:13.104 DEBUG (MainThread) [custom_components.solcast_solar] Hard limit: {'hard_limit_api': '100.0'}
2025-01-20 10:34:13.268 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Configuration directory is /workspaces/core/config
2025-01-20 10:34:13.268 DEBUG (MainThread) [custom_components.solcast_solar] Session headers: {'Accept': 'application/json', 'User-Agent': 'ha-solcast-solar-integration/4.2'}
2025-01-20 10:34:13.756 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Sites cache exists for ******wxbtdB
2025-01-20 10:34:13.757 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Connecting to https://api.solcast.com.au/rooftop_sites?format=json&api_key=******wxbtdB
2025-01-20 10:34:13.812 WARNING (MainThread) [custom_components.solcast_solar.solcastapi] HTTP session returned status 403/Forbidden, trying cache
2025-01-20 10:34:13.812 WARNING (MainThread) [custom_components.solcast_solar.solcastapi] Get sites failed, last call result: 403/Forbidden, using cached data
2025-01-20 10:34:13.812 INFO (MainThread) [custom_components.solcast_solar.solcastapi] Loading cached sites for ******wxbtdB
2025-01-20 10:34:13.836 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Sites data: {'sites': [{'name': 'BLAH', 'resource_id': 'a546-98c5-53c5-d101', 'capacity': 5, 'capacity_dc': 4.85, 'longitude': **.******, 'latitude': **.******, 'azimuth': -123, 'tilt': 5, 'install_date': '2012-04-18T14:00:00.0000000Z', 'loss_factor': 0.8, 'tags': ['Home', 'St Kilda West', 'Flat Roof', 'Home Assistant'], 'location': 'St Kilda West, VIC Australia', 'api_key': '******wxbtdB'}], 'page_count': 1, 'current_page': 1, 'total_records': 1}
2025-01-20 10:34:13.836 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Sites loaded
2025-01-20 10:34:13.837 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Checking rekey for ******wxbtdB
2025-01-20 10:34:13.837 INFO (MainThread) [custom_components.solcast_solar.solcastapi] API key ******wxbtdB has changed and sites are different invalidating the cache, not loading cached data
2025-01-20 10:34:24.208 DEBUG (MainThread) [custom_components.solcast_solar] Auto-update options: {'auto_update': 1}
2025-01-20 10:34:24.208 DEBUG (MainThread) [custom_components.solcast_solar] Estimate to use options: {'key_estimate': 'estimate'}
2025-01-20 10:34:24.208 DEBUG (MainThread) [custom_components.solcast_solar] Attribute options: {'attr_brk_detailed': False, 'attr_brk_estimate': True, 'attr_brk_estimate10': True, 'attr_brk_estimate90': True, 'attr_brk_halfhourly': True, 'attr_brk_hourly': True, 'attr_brk_site': True}
2025-01-20 10:34:24.209 DEBUG (MainThread) [custom_components.solcast_solar] Custom sensor options: {'customhoursensor': 1}
2025-01-20 10:34:24.209 DEBUG (MainThread) [custom_components.solcast_solar] Hard limit: {'hard_limit_api': '100.0'}
2025-01-20 10:34:24.212 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Configuration directory is /workspaces/core/config
2025-01-20 10:34:24.212 DEBUG (MainThread) [custom_components.solcast_solar] Session headers: {'Accept': 'application/json', 'User-Agent': 'ha-solcast-solar-integration/4.2'}
2025-01-20 10:34:24.225 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Sites cache exists for ******wxbtdB
2025-01-20 10:34:24.225 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Connecting to https://api.solcast.com.au/rooftop_sites?format=json&api_key=******wxbtdB
2025-01-20 10:34:24.252 WARNING (MainThread) [custom_components.solcast_solar.solcastapi] HTTP session returned status 403/Forbidden, trying cache
2025-01-20 10:34:24.255 WARNING (MainThread) [custom_components.solcast_solar.solcastapi] Get sites failed, last call result: 403/Forbidden, using cached data
2025-01-20 10:34:24.255 INFO (MainThread) [custom_components.solcast_solar.solcastapi] Loading cached sites for ******wxbtdB
2025-01-20 10:34:24.264 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Sites data: {'sites': [{'name': 'BLAH', 'resource_id': 'a546-98c5-53c5-d101', 'capacity': 5, 'capacity_dc': 4.85, 'longitude': **.******, 'latitude': **.******, 'azimuth': -123, 'tilt': 5, 'install_date': '2012-04-18T14:00:00.0000000Z', 'loss_factor': 0.8, 'tags': ['Home', 'St Kilda West', 'Flat Roof', 'Home Assistant'], 'location': 'St Kilda West, VIC Australia', 'api_key': '******wxbtdB'}], 'page_count': 1, 'current_page': 1, 'total_records': 1}
2025-01-20 10:34:24.264 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Sites loaded
2025-01-20 10:34:24.264 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Checking rekey for ******wxbtdB
2025-01-20 10:34:24.264 INFO (MainThread) [custom_components.solcast_solar.solcastapi] API key ******wxbtdB has changed and sites are different invalidating the cache, not loading cached data
2025-01-20 10:34:44.515 DEBUG (MainThread) [custom_components.solcast_solar] Auto-update options: {'auto_update': 1}
2025-01-20 10:34:44.516 DEBUG (MainThread) [custom_components.solcast_solar] Estimate to use options: {'key_estimate': 'estimate'}
2025-01-20 10:34:44.516 DEBUG (MainThread) [custom_components.solcast_solar] Attribute options: {'attr_brk_detailed': False, 'attr_brk_estimate': True, 'attr_brk_estimate10': True, 'attr_brk_estimate90': True, 'attr_brk_halfhourly': True, 'attr_brk_hourly': True, 'attr_brk_site': True}
2025-01-20 10:34:44.516 DEBUG (MainThread) [custom_components.solcast_solar] Custom sensor options: {'customhoursensor': 1}
2025-01-20 10:34:44.516 DEBUG (MainThread) [custom_components.solcast_solar] Hard limit: {'hard_limit_api': '100.0'}
2025-01-20 10:34:44.523 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Configuration directory is /workspaces/core/config
2025-01-20 10:34:44.523 DEBUG (MainThread) [custom_components.solcast_solar] Session headers: {'Accept': 'application/json', 'User-Agent': 'ha-solcast-solar-integration/4.2'}
2025-01-20 10:34:44.547 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Sites cache exists for ******wxbtdB
2025-01-20 10:34:44.547 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Connecting to https://api.solcast.com.au/rooftop_sites?format=json&api_key=******wxbtdB
2025-01-20 10:34:44.679 WARNING (MainThread) [custom_components.solcast_solar.solcastapi] HTTP session returned status 403/Forbidden, trying cache
2025-01-20 10:34:44.683 WARNING (MainThread) [custom_components.solcast_solar.solcastapi] Get sites failed, last call result: 403/Forbidden, using cached data
2025-01-20 10:34:44.684 INFO (MainThread) [custom_components.solcast_solar.solcastapi] Loading cached sites for ******wxbtdB
2025-01-20 10:34:44.698 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Sites data: {'sites': [{'name': 'BLAH', 'resource_id': 'a546-98c5-53c5-d101', 'capacity': 5, 'capacity_dc': 4.85, 'longitude': **.******, 'latitude': **.******, 'azimuth': -123, 'tilt': 5, 'install_date': '2012-04-18T14:00:00.0000000Z', 'loss_factor': 0.8, 'tags': ['Home', 'St Kilda West', 'Flat Roof', 'Home Assistant'], 'location': 'St Kilda West, VIC Australia', 'api_key': '******wxbtdB'}], 'page_count': 1, 'current_page': 1, 'total_records': 1}
2025-01-20 10:34:44.699 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Sites loaded
2025-01-20 10:34:44.699 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Checking rekey for ******wxbtdB
2025-01-20 10:34:44.699 INFO (MainThread) [custom_components.solcast_solar.solcastapi] API key ******wxbtdB has changed and sites are different invalidating the cache, not loading cached data
2025-01-20 10:35:25.007 DEBUG (MainThread) [custom_components.solcast_solar] Auto-update options: {'auto_update': 1}
2025-01-20 10:35:25.009 DEBUG (MainThread) [custom_components.solcast_solar] Estimate to use options: {'key_estimate': 'estimate'}
2025-01-20 10:35:25.009 DEBUG (MainThread) [custom_components.solcast_solar] Attribute options: {'attr_brk_detailed': False, 'attr_brk_estimate': True, 'attr_brk_estimate10': True, 'attr_brk_estimate90': True, 'attr_brk_halfhourly': True, 'attr_brk_hourly': True, 'attr_brk_site': True}
2025-01-20 10:35:25.009 DEBUG (MainThread) [custom_components.solcast_solar] Custom sensor options: {'customhoursensor': 1}
2025-01-20 10:35:25.009 DEBUG (MainThread) [custom_components.solcast_solar] Hard limit: {'hard_limit_api': '100.0'}
2025-01-20 10:35:25.033 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Configuration directory is /workspaces/core/config
2025-01-20 10:35:25.035 DEBUG (MainThread) [custom_components.solcast_solar] Session headers: {'Accept': 'application/json', 'User-Agent': 'ha-solcast-solar-integration/4.2'}
2025-01-20 10:35:25.092 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Sites cache exists for ******wxbtdB
2025-01-20 10:35:25.093 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Connecting to https://api.solcast.com.au/rooftop_sites?format=json&api_key=******wxbtdB
2025-01-20 10:35:25.463 WARNING (MainThread) [custom_components.solcast_solar.solcastapi] HTTP session returned status 403/Forbidden, trying cache
2025-01-20 10:35:25.470 WARNING (MainThread) [custom_components.solcast_solar.solcastapi] Get sites failed, last call result: 403/Forbidden, using cached data
2025-01-20 10:35:25.470 INFO (MainThread) [custom_components.solcast_solar.solcastapi] Loading cached sites for ******wxbtdB
2025-01-20 10:35:25.492 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Sites data: {'sites': [{'name': 'BLAH', 'resource_id': 'a546-98c5-53c5-d101', 'capacity': 5, 'capacity_dc': 4.85, 'longitude': **.******, 'latitude': **.******, 'azimuth': -123, 'tilt': 5, 'install_date': '2012-04-18T14:00:00.0000000Z', 'loss_factor': 0.8, 'tags': ['Home', 'St Kilda West', 'Flat Roof', 'Home Assistant'], 'location': 'St Kilda West, VIC Australia', 'api_key': '******wxbtdB'}], 'page_count': 1, 'current_page': 1, 'total_records': 1}
2025-01-20 10:35:25.492 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Sites loaded
2025-01-20 10:35:25.492 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Checking rekey for ******wxbtdB
2025-01-20 10:35:25.492 INFO (MainThread) [custom_components.solcast_solar.solcastapi] API key ******wxbtdB has changed and sites are different invalidating the cache, not loading cached data

@BJReplay
Copy link
Owner

Prod test successful:

image

Log:

homeassistant  | 2025-01-20 10:38:50.274 INFO (MainThread) [custom_components.solcast_solar.coordinator] Auto update forecast
homeassistant  | 2025-01-20 10:38:50.275 DEBUG (MainThread) [custom_components.solcast_solar.coordinator] Started task pending_update_207
homeassistant  | 2025-01-20 10:38:50.275 DEBUG (MainThread) [custom_components.solcast_solar.coordinator] Checking for stale usage cache
homeassistant  | 2025-01-20 10:38:50.275 INFO (MainThread) [custom_components.solcast_solar.solcastapi] Getting forecast update for site a546-98c5-53c5-d101
homeassistant  | 2025-01-20 10:38:50.275 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Polling API for site a546-98c5-53c5-d101, last day 2025-01-27, 182 hours
homeassistant  | 2025-01-20 10:38:50.276 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Fetching forecast
homeassistant  | 2025-01-20 10:38:50.330 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Fetch data url https://api.solcast.com.au/rooftop_sites/a546-98c5-53c5-d101/forecasts?format=json&api_key=******wxbtdB&hours=182
homeassistant  | 2025-01-20 10:38:50.330 ERROR (MainThread) [custom_components.solcast_solar.solcastapi] API key ******wxbtdB is forbidden, re-authentication required
homeassistant  | 2025-01-20 10:38:50.330 ERROR (MainThread) [custom_components.solcast_solar.solcastapi] No data was returned for forecasts
homeassistant  | 2025-01-20 10:38:50.330 WARNING (MainThread) [custom_components.solcast_solar.solcastapi] Forecast update for site a546-98c5-53c5-d101 failed
homeassistant  | 2025-01-20 10:38:50.330 WARNING (MainThread) [custom_components.solcast_solar.solcastapi] Forecast has not been updated, next auto update at 11:21:40
homeassistant  | 2025-01-20 10:38:50.341 ERROR (MainThread) [custom_components.solcast_solar.coordinator] Authentication failed while fetching solcast_solar data: API key is invalid
homeassistant  | 2025-01-20 10:38:50.342 DEBUG (MainThread) [custom_components.solcast_solar.coordinator] Finished fetching solcast_solar data in 0.002 seconds (success: False)
homeassistant  | 2025-01-20 10:38:50.343 DEBUG (MainThread) [custom_components.solcast_solar.coordinator] Completed task pending_update_207
homeassistant  | 2025-01-20 10:43:08.917 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Configuration directory is /config
homeassistant  | 2025-01-20 10:43:08.918 DEBUG (MainThread) [custom_components.solcast_solar] Session headers: {'Accept': 'application/json', 'User-Agent': 'ha-solcast-solar-integration/4.2'}
homeassistant  | 2025-01-20 10:43:08.918 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Test connection to https://api.solcast.com.au/rooftop_sites?format=json&api_key=******bKxB8X
homeassistant  | 2025-01-20 10:43:09.063 DEBUG (MainThread) [custom_components.solcast_solar] Options updated, action: The integration will reload
homeassistant  | 2025-01-20 10:43:09.064 DEBUG (MainThread) [custom_components.solcast_solar.coordinator] Cancelling coordinator task listeners
homeassistant  | 2025-01-20 10:43:09.064 DEBUG (MainThread) [custom_components.solcast_solar.coordinator] Cancelling coordinator task check_fetch
homeassistant  | 2025-01-20 10:43:09.064 DEBUG (MainThread) [custom_components.solcast_solar.coordinator] Cancelling coordinator task midnight_update
homeassistant  | 2025-01-20 10:43:09.076 DEBUG (MainThread) [custom_components.solcast_solar] Remove action: solcast_solar.clear_all_solcast_data
homeassistant  | 2025-01-20 10:43:09.077 DEBUG (MainThread) [custom_components.solcast_solar] Remove action: solcast_solar.force_update_forecasts
homeassistant  | 2025-01-20 10:43:09.077 DEBUG (MainThread) [custom_components.solcast_solar] Remove action: solcast_solar.get_dampening
homeassistant  | 2025-01-20 10:43:09.077 DEBUG (MainThread) [custom_components.solcast_solar] Remove action: solcast_solar.query_forecast_data
homeassistant  | 2025-01-20 10:43:09.077 DEBUG (MainThread) [custom_components.solcast_solar] Remove action: solcast_solar.remove_hard_limit
homeassistant  | 2025-01-20 10:43:09.077 DEBUG (MainThread) [custom_components.solcast_solar] Remove action: solcast_solar.set_dampening
homeassistant  | 2025-01-20 10:43:09.078 DEBUG (MainThread) [custom_components.solcast_solar] Remove action: solcast_solar.set_hard_limit
homeassistant  | 2025-01-20 10:43:09.082 DEBUG (MainThread) [custom_components.solcast_solar] Remove action: solcast_solar.update_forecasts
homeassistant  | 2025-01-20 10:43:09.083 DEBUG (MainThread) [custom_components.solcast_solar] Auto-update options: {'auto_update': 1}
homeassistant  | 2025-01-20 10:43:09.083 DEBUG (MainThread) [custom_components.solcast_solar] Estimate to use options: {'key_estimate': 'estimate'}
homeassistant  | 2025-01-20 10:43:09.084 DEBUG (MainThread) [custom_components.solcast_solar] Attribute options: {'attr_brk_detailed': False, 'attr_brk_estimate': False, 'attr_brk_estimate10': True, 'attr_brk_estimate90': False, 'attr_brk_halfhourly': True, 'attr_brk_hourly': False, 'attr_brk_site': False}
homeassistant  | 2025-01-20 10:43:09.084 DEBUG (MainThread) [custom_components.solcast_solar] Custom sensor options: {'customhoursensor': 2}
homeassistant  | 2025-01-20 10:43:09.084 DEBUG (MainThread) [custom_components.solcast_solar] Hard limit: {'hard_limit_api': '100.0'}
homeassistant  | 2025-01-20 10:43:09.092 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Configuration directory is /config
homeassistant  | 2025-01-20 10:43:09.092 DEBUG (MainThread) [custom_components.solcast_solar] Session headers: {'Accept': 'application/json', 'User-Agent': 'ha-solcast-solar-integration/4.2'}
homeassistant  | 2025-01-20 10:43:09.119 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Sites cache exists for ******bKxB8X
homeassistant  | 2025-01-20 10:43:09.119 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Connecting to https://api.solcast.com.au/rooftop_sites?format=json&api_key=******bKxB8X
homeassistant  | 2025-01-20 10:43:09.154 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] HTTP session returned status 200/Success
homeassistant  | 2025-01-20 10:43:09.154 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Sites data: {'sites': [{'name': 'BLAH', 'resource_id': 'a546-98c5-53c5-d101', 'capacity': 5, 'capacity_dc': 4.85, 'longitude': **.******, 'latitude': **.******, 'azimuth': -123, 'tilt': 5, 'install_date': '2012-04-18T14:00:00.0000000Z', 'loss_factor': 0.8, 'tags': ['Home', 'St Kilda West', 'Flat Roof', 'Home Assistant'], 'location': 'St Kilda West, VIC Australia', 'api_key': '******bKxB8X'}], 'page_count': 1, 'current_page': 1, 'total_records': 1}
homeassistant  | 2025-01-20 10:43:09.154 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Sites loaded
homeassistant  | 2025-01-20 10:43:09.155 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Checking rekey for ******bKxB8X
homeassistant  | 2025-01-20 10:43:09.155 INFO (MainThread) [custom_components.solcast_solar.solcastapi] API key ******bKxB8X has changed, migrating API usage
homeassistant  | 2025-01-20 10:43:09.155 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Writing sites cache for ******bKxB8X
homeassistant  | 2025-01-20 10:43:09.157 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Usage cache exists for ******bKxB8X
homeassistant  | 2025-01-20 10:43:09.157 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Usage cache for ******bKxB8X last reset 2025-01-19 11:00:00
homeassistant  | 2025-01-20 10:43:09.158 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Usage loaded
homeassistant  | 2025-01-20 10:43:09.158 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] API counter for ******bKxB8X is 11/20
homeassistant  | 2025-01-20 10:43:09.159 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Using legacy hourly dampening
homeassistant  | 2025-01-20 10:43:09.186 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Data cache /config/solcast.json exists, file type is <class 'dict'>
homeassistant  | 2025-01-20 10:43:09.186 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Dampened data loaded
homeassistant  | 2025-01-20 10:43:09.192 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Data cache /config/solcast-undampened.json exists, file type is <class 'dict'>
homeassistant  | 2025-01-20 10:43:09.192 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Un-dampened data loaded
homeassistant  | 2025-01-20 10:43:09.241 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Task build_data took 0.047 seconds
homeassistant  | 2025-01-20 10:43:09.270 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Forecast data from 2025-01-20 to 2025-01-27 contains all intervals
homeassistant  | 2025-01-20 10:43:09.273 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Task recalculate_splines took 0.002 seconds
homeassistant  | 2025-01-20 10:43:09.274 DEBUG (MainThread) [custom_components.solcast_solar.coordinator] Sun rise / set today: 06:20:15 / 20:41:27
homeassistant  | 2025-01-20 10:43:09.274 DEBUG (MainThread) [custom_components.solcast_solar.coordinator] Auto update total seconds: 51672, divisions: 20, interval: 2583 seconds
homeassistant  | 2025-01-20 10:43:09.274 DEBUG (MainThread) [custom_components.solcast_solar.coordinator] Auto update forecasts between sunrise and sunset
homeassistant  | 2025-01-20 10:43:09.274 DEBUG (MainThread) [custom_components.solcast_solar.coordinator] Previous auto update would have been at 10:38:36
homeassistant  | 2025-01-20 10:43:09.274 INFO (MainThread) [custom_components.solcast_solar.coordinator] Auto forecast updates for today at 11:21, 12:04, 12:47, 13:30, 14:13, 14:56, 15:40, 16:23, 17:06, 17:49, 18:32, 19:15, 19:58
homeassistant  | 2025-01-20 10:43:09.274 INFO (MainThread) [custom_components.solcast_solar.coordinator] Auto forecast updates for tomorrow at 06:21, 07:04, 07:47, 08:30, 09:13, 09:56, 10:39, 11:22, 12:05, 12:48, 13:31, 14:14, 14:57, 15:40, 16:23, 17:06, 17:48, 18:31, 19:14, 19:57
homeassistant  | 2025-01-20 10:43:09.274 DEBUG (MainThread) [custom_components.solcast_solar.coordinator] Running task check_fetch
homeassistant  | 2025-01-20 10:43:09.274 DEBUG (MainThread) [custom_components.solcast_solar.coordinator] Running task listeners
homeassistant  | 2025-01-20 10:43:09.274 DEBUG (MainThread) [custom_components.solcast_solar.coordinator] Running task midnight_update
homeassistant  | 2025-01-20 10:43:09.274 DEBUG (MainThread) [custom_components.solcast_solar.coordinator] Finished fetching solcast_solar data in 0.000 seconds (success: True)
homeassistant  | 2025-01-20 10:43:09.275 DEBUG (MainThread) [custom_components.solcast_solar] UTC times are converted to Australia/Sydney
homeassistant  | 2025-01-20 10:43:09.275 DEBUG (MainThread) [custom_components.solcast_solar] Successful init
homeassistant  | 2025-01-20 10:43:09.275 INFO (MainThread) [custom_components.solcast_solar] Solcast integration version: 4.2.8
homeassistant  | 2025-01-20 10:43:09.296 DEBUG (MainThread) [custom_components.solcast_solar] Checking whether auto update forecast is stale
homeassistant  | 2025-01-20 10:43:09.296 INFO (MainThread) [custom_components.solcast_solar] Last auto update forecast recorded (2025-01-20 09:55:35) is older than expected, should be (2025-01-20 10:38:36), updating forecast
homeassistant  | 2025-01-20 10:43:09.296 DEBUG (MainThread) [custom_components.solcast_solar] Register action: solcast_solar.clear_all_solcast_data
homeassistant  | 2025-01-20 10:43:09.296 DEBUG (MainThread) [custom_components.solcast_solar] Register action: solcast_solar.force_update_forecasts
homeassistant  | 2025-01-20 10:43:09.296 DEBUG (MainThread) [custom_components.solcast_solar] Register action: solcast_solar.get_dampening
homeassistant  | 2025-01-20 10:43:09.297 DEBUG (MainThread) [custom_components.solcast_solar] Register action: solcast_solar.query_forecast_data
homeassistant  | 2025-01-20 10:43:09.297 DEBUG (MainThread) [custom_components.solcast_solar] Register action: solcast_solar.remove_hard_limit
homeassistant  | 2025-01-20 10:43:09.297 DEBUG (MainThread) [custom_components.solcast_solar] Register action: solcast_solar.set_dampening
homeassistant  | 2025-01-20 10:43:09.297 DEBUG (MainThread) [custom_components.solcast_solar] Register action: solcast_solar.set_hard_limit
homeassistant  | 2025-01-20 10:43:09.297 DEBUG (MainThread) [custom_components.solcast_solar] Register action: solcast_solar.update_forecasts
homeassistant  | 2025-01-20 10:43:09.297 DEBUG (MainThread) [custom_components.solcast_solar.coordinator] Started task update_missed
homeassistant  | 2025-01-20 10:43:09.297 DEBUG (MainThread) [custom_components.solcast_solar.coordinator] Checking for stale usage cache
homeassistant  | 2025-01-20 10:43:09.297 INFO (MainThread) [custom_components.solcast_solar.solcastapi] Getting forecast update for site a546-98c5-53c5-d101
homeassistant  | 2025-01-20 10:43:09.297 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Polling API for site a546-98c5-53c5-d101, last day 2025-01-27, 182 hours
homeassistant  | 2025-01-20 10:43:09.297 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Fetching forecast
homeassistant  | 2025-01-20 10:43:09.777 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Fetch data url https://api.solcast.com.au/rooftop_sites/a546-98c5-53c5-d101/forecasts?format=json&api_key=******bKxB8X&hours=182
homeassistant  | 2025-01-20 10:43:09.777 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] API returned data, API counter incremented from 11 to 12
homeassistant  | 2025-01-20 10:43:09.777 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Writing API usage cache file: /config/solcast-usage.json
homeassistant  | 2025-01-20 10:43:09.799 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Task fetch_data took 0.502 seconds
homeassistant  | 2025-01-20 10:43:09.799 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] 365 records returned
homeassistant  | 2025-01-20 10:43:09.819 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Task load_new_data took 0.020 seconds
homeassistant  | 2025-01-20 10:43:09.822 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Task apply_dampening took 0.002 seconds
homeassistant  | 2025-01-20 10:43:09.889 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Task sort_and_prune took 0.067 seconds
homeassistant  | 2025-01-20 10:43:09.889 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Forecasts dictionary length 7341 (1056 un-dampened)
homeassistant  | 2025-01-20 10:43:09.946 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Task build_data took 0.056 seconds
homeassistant  | 2025-01-20 10:43:09.980 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Forecast data from 2025-01-20 to 2025-01-27 contains all intervals
homeassistant  | 2025-01-20 10:43:09.982 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Task recalculate_splines took 0.002 seconds
homeassistant  | 2025-01-20 10:43:10.036 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Saved dampened forecast cache
homeassistant  | 2025-01-20 10:43:10.044 DEBUG (MainThread) [custom_components.solcast_solar.solcastapi] Saved un-dampened forecast cache
homeassistant  | 2025-01-20 10:43:10.044 INFO (MainThread) [custom_components.solcast_solar.solcastapi] Forecast update completed successfully
homeassistant  | 2025-01-20 10:43:10.056 DEBUG (MainThread) [custom_components.solcast_solar.coordinator] Finished fetching solcast_solar data in 0.000 seconds (success: True)
homeassistant  | 2025-01-20 10:43:10.057 DEBUG (MainThread) [custom_components.solcast_solar.coordinator] Completed task update_missed

@autoSteve
Copy link
Collaborator Author

The sites comparison is failing for your dev container, so initial cache load is refused. That should not have happened, as your sites have not changed, and the cache should be used.

Thinking about this situation the integration should fail hard as it did correctly if the sites are different, but re-auth should definitely be shown. Startup may not be raising that HA exception.

I will try to replicate using the same start sequence. (This scenario may not currently be covered by the PyTest suite, but will check whether I coded it. I am definitely testing the forecast fetch failure sequence, and there is 100% coverage again, so it would suprise me if it's not.)

Good news for the more common scenario of 403 on forecast fetch in prod!

@autoSteve
Copy link
Collaborator Author

This scenario was not covered by the PyTest suite. It is now.

Code still has startup issues.

@BJReplay
Copy link
Owner

Noticed something funky - dunno if it is HA or a side effect from changing how config is stored - will look into it, but figured I'd test the latest code by editing the API key in core.config_entries in my Dev Container.

I changed the redacted - old key that I changed this morning in the data dict initially (since that was the one I could see without scrolling right) rather than the new key in the options dict.

Just wondering if this might be the reason why you're seeing double restarts and other odd behaviour - two different sets of data stored - options and data?

I will remove the integration and clean up old entries to explore more, but thought I'd post what I saw here.

{
  "version": 1,
  "minor_version": 4,
  "key": "core.config_entries",
  "data": {
    "entries": [
      {"created_at":"2024-11-05T22:33:49.065844+00:00","data":{},"disabled_by":null,"discovery_keys":{},"domain":"sun","entry_id":"01JBZ7CX892Q3CHBQ8VM7GS1HD","minor_version":1,"modified_at":"2024-11-05T22:33:49.065851+00:00","options":{},"pref_disable_new_entities":false,"pref_disable_polling":false,"source":"import","title":"Sun","unique_id":null,"version":1},
      {"created_at":"2024-11-05T22:48:54.978705+00:00","data":{"token":"redacted"},"disabled_by":null,"discovery_keys":{},"domain":"hacs","entry_id":"01JBZ88HY2DAX0811MTMJXHG5G","minor_version":1,"modified_at":"2024-11-05T22:48:54.978725+00:00","options":{"experimental":true},"pref_disable_new_entities":false,"pref_disable_polling":false,"source":"user","title":"","unique_id":null,"version":1},
      {"created_at":"2024-11-19T23:08:45.651933+00:00","data":{},"disabled_by":null,"discovery_keys":{},"domain":"epa_victoria_air_quality","entry_id":"01JD3AYYPKNCF1ZNW6BCBGS34Q","minor_version":1,"modified_at":"2024-11-19T23:08:45.651939+00:00","options":{"api_key":"redacted","site_id":"4afe6adc-cbac-4bf1-afbe-ff98d59564f9"},"pref_disable_new_entities":false,"pref_disable_polling":false,"source":"user","title":"EPA Air Quality","unique_id":null,"version":2},
      {"created_at":"2024-11-28T03:53:59.551705+00:00","data":{},"disabled_by":null,"discovery_keys":{},"domain":"spook","entry_id":"01JDREEZFZCA3WRRD4S94P9P23","minor_version":1,"modified_at":"2024-11-28T03:53:59.551714+00:00","options":{},"pref_disable_new_entities":false,"pref_disable_polling":false,"source":"user","title":"Your homie","unique_id":null,"version":1},
      {"created_at":"2024-12-10T05:30:40.496122+00:00","data":{},"disabled_by":null,"discovery_keys":{},"domain":"sew_usage","entry_id":"01JEQGRMFGVH6BJNY8MW320DJN","minor_version":1,"modified_at":"2024-12-10T05:30:40.496132+00:00","options":{"browserless":"http://192.168.1.200:3000","install_date":"2024-12-10","mains_water_serial":"redacted","password":"redacted","recycled_water_serial":"","token":"redacted","username":"redacted"},"pref_disable_new_entities":false,"pref_disable_polling":false,"source":"user","title":"South East Water Usage","unique_id":null,"version":1},
      {"created_at":"2025-01-13T00:57:50.462204+00:00","data":{"api_key":"redacted - old key that I changed this morning","api_quota":"10","attr_brk_detailed":false,"attr_brk_estimate":true,"attr_brk_estimate10":true,"attr_brk_estimate90":true,"attr_brk_halfhourly":true,"attr_brk_hourly":true,"attr_brk_site":true,"auto_update":1,"customhoursensor":1,"damp00":1.0,"damp01":1.0,"damp02":1.0,"damp03":1.0,"damp04":1.0,"damp05":1.0,"damp06":1.0,"damp07":1.0,"damp08":1.0,"damp09":1.0,"damp10":1.0,"damp11":1.0,"damp12":1.0,"damp13":1.0,"damp14":1.0,"damp15":1.0,"damp16":1.0,"damp17":1.0,"damp18":1.0,"damp19":1.0,"damp20":1.0,"damp21":1.0,"damp22":1.0,"damp23":1.0,"hard_limit_api":"100.0","key_estimate":"estimate","site_damp":false},"disabled_by":null,"discovery_keys":{},"domain":"solcast_solar","entry_id":"01JHEJNG3Y8Y7VTE1KNGQKX4K5","minor_version":1,"modified_at":"2025-01-19T23:45:20.063590+00:00","options":{"api_key":"redacted new key that I created this morning","api_quota":"10","attr_brk_detailed":false,"attr_brk_estimate":true,"attr_brk_estimate10":true,"attr_brk_estimate90":true,"attr_brk_halfhourly":true,"attr_brk_hourly":true,"attr_brk_site":true,"auto_update":1,"customhoursensor":1,"damp00":1.0,"damp01":1.0,"damp02":1.0,"damp03":1.0,"damp04":1.0,"damp05":1.0,"damp06":1.0,"damp07":1.0,"damp08":1.0,"damp09":1.0,"damp10":1.0,"damp11":1.0,"damp12":1.0,"damp13":1.0,"damp14":1.0,"damp15":1.0,"damp16":1.0,"damp17":1.0,"damp18":1.0,"damp19":1.0,"damp20":1.0,"damp21":1.0,"damp22":1.0,"damp23":1.0,"hard_limit_api":"100.0","key_estimate":"estimate","site_damp":false},"pref_disable_new_entities":false,"pref_disable_polling":false,"source":"user","title":"Solcast Solar","unique_id":null,"version":14}
    ]
  }

@autoSteve
Copy link
Collaborator Author

Given I know exactly what was causing the double starts, no. The root was switching to a hass.config_entries function that updates the entry, reloads and returns the "success" message. I've switched back. It was double-starting because that particular hass.config_entries function schedules a restart, but before it got to that updating the config entry would shoot to the function in __init__.py which would make a determination that the integration wanted reloading because changed API key.

The doubling of things in the entry are because of me. Nicely spotted. There are two dict keys at play there, the first being "data", and the second "options". These are identical because config_flow.py reauth and reconfig flow.

The snip below is what happens when the integration is first configured, so "data" should be empty. I think the code that was causing the double reload did it because I'm fairly certain I mistakenly set "data" in that call. With latest code data sould be empty, but it won't get emptied if it's there right now unless the integration is re-set up.

If you want to manually hack it, delete all keys in "data", and change the key in "options".

return self.async_create_entry(title=TITLE, data={}, options=options | damp)

@BJReplay
Copy link
Owner

If you want to manually hack it, delete all keys in "data", and change the key in "options".

I deleted everything solcast from the config folder, and from core.config_entries, core.device_registry, and core.entity_registry:

New core.config_entries looks just fine:

{
  "version": 1,
  "minor_version": 4,
  "key": "core.config_entries",
  "data": {
    "entries": [
      {"created_at":"2024-11-05T22:33:49.065844+00:00","data":{},"disabled_by":null,"discovery_keys":{},"domain":"sun","entry_id":"01JBZ7CX892Q3CHBQ8VM7GS1HD","minor_version":1,"modified_at":"2024-11-05T22:33:49.065851+00:00","options":{},"pref_disable_new_entities":false,"pref_disable_polling":false,"source":"import","title":"Sun","unique_id":null,"version":1},
      {"created_at":"2024-11-05T22:48:54.978705+00:00","data":{"token":"redacted"},"disabled_by":null,"discovery_keys":{},"domain":"hacs","entry_id":"01JBZ88HY2DAX0811MTMJXHG5G","minor_version":1,"modified_at":"2024-11-05T22:48:54.978725+00:00","options":{"experimental":true},"pref_disable_new_entities":false,"pref_disable_polling":false,"source":"user","title":"","unique_id":null,"version":1},
      {"created_at":"2024-11-19T23:08:45.651933+00:00","data":{},"disabled_by":null,"discovery_keys":{},"domain":"epa_victoria_air_quality","entry_id":"01JD3AYYPKNCF1ZNW6BCBGS34Q","minor_version":1,"modified_at":"2024-11-19T23:08:45.651939+00:00","options":{"api_key":"redacted","site_id":"4afe6adc-cbac-4bf1-afbe-ff98d59564f9"},"pref_disable_new_entities":false,"pref_disable_polling":false,"source":"user","title":"EPA Air Quality","unique_id":null,"version":2},
      {"created_at":"2024-11-28T03:53:59.551705+00:00","data":{},"disabled_by":null,"discovery_keys":{},"domain":"spook","entry_id":"01JDREEZFZCA3WRRD4S94P9P23","minor_version":1,"modified_at":"2024-11-28T03:53:59.551714+00:00","options":{},"pref_disable_new_entities":false,"pref_disable_polling":false,"source":"user","title":"Your homie","unique_id":null,"version":1},
      {"created_at":"2024-12-10T05:30:40.496122+00:00","data":{},"disabled_by":null,"discovery_keys":{},"domain":"sew_usage","entry_id":"01JEQGRMFGVH6BJNY8MW320DJN","minor_version":1,"modified_at":"2024-12-10T05:30:40.496132+00:00","options":{"browserless":"http://192.168.1.200:3000","install_date":"2024-12-10","mains_water_serial":"redacted","password":"redacted","recycled_water_serial":"","token":"redacted","username":"redacted"},"pref_disable_new_entities":false,"pref_disable_polling":false,"source":"user","title":"South East Water Usage","unique_id":null,"version":1},
      {"created_at":"2025-01-20T04:56:10.305042+00:00","data":{},"disabled_by":null,"discovery_keys":{},"domain":"solcast_solar","entry_id":"01JJ112XT017FVGCF0S84VMBM0","minor_version":1,"modified_at":"2025-01-20T04:56:10.538323+00:00","options":{"api_key":"redacted","api_quota":"10","attr_brk_detailed":false,"attr_brk_estimate":true,"attr_brk_estimate10":true,"attr_brk_estimate90":true,"attr_brk_halfhourly":true,"attr_brk_hourly":true,"attr_brk_site":true,"auto_update":1,"customhoursensor":1,"damp00":1.0,"damp01":1.0,"damp02":1.0,"damp03":1.0,"damp04":1.0,"damp05":1.0,"damp06":1.0,"damp07":1.0,"damp08":1.0,"damp09":1.0,"damp10":1.0,"damp11":1.0,"damp12":1.0,"damp13":1.0,"damp14":1.0,"damp15":1.0,"damp16":1.0,"damp17":1.0,"damp18":1.0,"damp19":1.0,"damp20":1.0,"damp21":1.0,"damp22":1.0,"damp23":1.0,"hard_limit_api":"100.0","key_estimate":"estimate","site_damp":false},"pref_disable_new_entities":false,"pref_disable_polling":false,"source":"user","title":"Solcast Solar","unique_id":null,"version":14},
    ]
  }
}

Will get back to testing other stuff including API key rotation.

@autoSteve
Copy link
Collaborator Author

Perfect.

@BJReplay
Copy link
Owner

And tested key rotation with HA shutdown - works nicely with your latest (approx 3:15) commit.

@BJReplay
Copy link
Owner

One more thing - I'm not sure if this is my configuration, or code changes, but I think it is code changes:

4.2.7

image

image

4.2.8 (with same configuration)

image

Noticed because

image

@autoSteve
Copy link
Collaborator Author

Interesting.

I can't replicate that in dev, plus with data that bad PyTest would spew it's guts.

SFTP is currently broken for me to transfer files to prod, so I'll need to fix that and get the code running somewhere real.

image

@autoSteve
Copy link
Collaborator Author

The ziggly line would be your updates getting fwesh forecasts from Solcast I would think. Looks like ten adjustments from sunrise to sunset, so sensor updates are deffo working!.

I'll try those exact settings in the dev container.

@autoSteve
Copy link
Collaborator Author

That's a bona fide bug.

image

@autoSteve
Copy link
Collaborator Author

I'm actually really embarrassed about that one. Dicked logic.

Fixed the options flow translatable confirmation message while I was down there. I believe we have everything seen in the UI translatable. As I find more I fix more, but haven't found one since the options flow.

@BJReplay
Copy link
Owner

Fixed the options flow translatable confirmation message

I had noticed that, but hadn't checked if the issue was that I hadn't successfully copied the translations or refreshed the cache, so hadn't mentioned it - yet 🤣.

@BJReplay
Copy link
Owner

Note: also fixes #233

And shift some exceptions for testing.

Sensors disabled are day 3-7 forecast and the custom X hour sensor.
@autoSteve
Copy link
Collaborator Author

The day 3-7 sensors, and the custom X hour sensor can't be used by many folk, so now they are disabled by default for a new install.

There should not be any change for existing installations.

My standards are slipping... I'll think about that tomoz.

Name                                                                                     Stmts   Miss  Cover   Missing
----------------------------------------------------------------------------------------------------------------------
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/__init__.py          360      0   100%
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/config_flow.py       219      2    99%   194, 240
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/const.py              42      0   100%
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/coordinator.py       266      0   100%
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/diagnostics.py        16      0   100%
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/energy.py             15      0   100%
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/select.py             42      0   100%
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/sensor.py            160      0   100%
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/solcastapi.py       1440      0   100%
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/system_health.py      11      0   100%
/workspaces/homeAssistant-core/homeassistant/components/solcast_solar/util.py               95      0   100%
----------------------------------------------------------------------------------------------------------------------
TOTAL                                                                                     2666      2    99%

@autoSteve
Copy link
Collaborator Author

autoSteve commented Jan 20, 2025

(Commit fail. hassfest does not like icon "translations". Neither do I. They do not work for me probably because class defaults. Not that that fact is documented anywhere... It's hard to evolve ones's quality standard when things don't even work as described. Quality #unobtanium. I'm almost done with the check list. And that does not mean I've almost done it. It means I'm about to throw it against a wall. In disgust and then stomp on it when it is dead, and then consider urinating on it... Which might be a bit harsh. I mean to say I am about to completely disregard it's finicky bits. You and I have quality here. Unmeasured.)

BTW, as an example, technically this lot does not pass "bronze". Services are not set up in async_setup(). This is mandatory. I've looked for quite a few more hours than I should have at this... No deal for now. I may find a way some day.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Migration from Oziee v3.x.x fails with a log full of UnboundLocalError 'index' issues
3 participants