I think what I'm lacking is a mental model of how to approach high level code, where I can't be sure what its doing under the hood (and also not mentally knowing the entire 'API' mentally, unlike is the case with hardware HALs). I seem to have lost it in the way somewhere. I used to program in QBASIC, VB6, and a bunch of high level languages in the past and I was fairly happy doing it.
I think you might consider reframing or moving to a different perspective.
The number one defining thing about a "higher" level language and why we call it "higher" is that somethings are done for you or taken from you and conventialised.
Consider moving from ASM to C. When you did it ASM you dealt with things like "Calling convention, argument passing, return value passing, addressing modes, etc. etc." When you do it in C, the C runtime decides all that with help of the linker.
When you go up another level to the likes of Java and some of the things you used to have to do in C, like memory management and may have even implemented a "pattern" in your own code base to provide minimal "management" over memory and allocations/deallocations. Java wraps that for you, for example. Now your pointers are managed and not direct memory references at all, but done in a way that you don't need to know.
Each of them C, C++, Java come with "Standard libraries" sometimes called the "The API". In C its usually some form of CRT and stdlib. C++ has similar and extends with the, streams, collection and container template libs etc. Java has the JVM API.
To learn a new high-level language it is critical to start with the language itself. To learn Java or learn Python start learning them in their "out of the box" form. Avoid tutorials which "Use this with that to do..." if "this" and "that" are not part of the languages default, core, API.
This will teach you the form, style, conventions and the interface to the layer below. The later will usually be familiar coming up from lower down and alien going the other way.
When you can tell what "Vanilla" Java or Python looks like, then when you read someone's application you will immediately know to look for things like dependencies, frameworks, libraries, sub-systems. The core language then becomes just the fabric the larger system is built with from big chunky fat libraries.
On HomeAssistant. That is not an easy first grasp of "high level" software design. I would not work in that code base by choice. It does highlight something which is very common and can be very frustrating. Large open source code bases work a bit like governments. They aim to try and support everyone and make the software all things to all people and end up, ultimately failing miserably and becoming indebted to their own complexity and bureaucracy until they can no longer progress. Unless they have a vicious dog like Linus Torvalds guarding the main line branches.
Do not worry if you fear the nomeclature and structure in home assistant, "Platform", Entity, Device are okay, but then it just gets weird. I have been writing code for 40+ years, high and low and ... I would not work in the HA code base unless they paid me to... a lot.
I would say, as a learner project, don't try and "integrate" with HA at the code level. Start with a lower level like the MQTT message bus or other "wire" protocol which HA already supports. That component will be FAR simplier and teach you far more.
Also... Python, whether python fanboys like it or not, was NEVER designed to handle large complex applications. Python is to C what Javascript is to the browser APIs. It is literally a utility script language so that C programmers didn't have to write "admin and utils" in C.
Python itself might be a bad choice to move up to. Partly because a lot of people don't agree with my prior statement. Why? They only know python, only ever learnt python and have no other persepective or model to work from.
However, python, as a wrapper around C is fine. It's extremely opinionated, quirky and has syntax and grammar not found in other languages such as "list comprehension" operators. It's "white space" dependant. Formating matters.
To learn upwards from C/C++ something like Java or C# might be a better intro to "Virtual Machine" modern highlevel eco systems.
EDIT:
On structure and design of complexity. Again using the analogy that in ASM/C you made up your own patterns, utilities, wrappers or borrowed from others or from text books. Consider the classic "C Module" which is a "struct" and a set of functions. It's only a step or two or syntactic sugar from OOP and a class.
In a large swaith of higher level languages this pattern was wrapped and the "OOP" buzz word was slapped on it. You will not avoid OOP. Some of it is surface thin, like it was in C, in others it's dogmatic and crippling, Java/C++. C# tries to find middle ground in some places less so in others. The point is, OOP is a running theme. Most langages can be "made to" do proceedural, but you'll get flamed for it.
Where this surfaces is in application layers where you have standard integrations like "HTTP". It's so common, you lift it out of most standard libraries directly. However. Most modern software stacks are going to want... HTTP+REST+SSL+OAUTH Authentication+Payload serdes. So... you would not "normally" go to the language API's lower level HTTP and start building. You would go and download a REST API layer which supports the full "standard" stack out of tne box.
Here you meet the abstractions and the frustrations, because that stack can be done in dozens of different ways and the component you choice supports all of them with complex dependency injection, aspect orientated / annotation programming and implied configuration from introspection.... all of those are "Intermediate to advanced" topics.
The only way to remain sane is to think at different layers with real ceilings and floors. However, you can still get into the elevator and go a floor up/down. Just try not to take any baggage with you. When on floor 5, floor 4 and 6 are outside of your scope, except as "integrations".