PeteRager / lennoxs30api

API for communication with Lennox S30 / E30 climate controls using Lennox cloud or local connection
MIT License
9 stars 2 forks source link

Add Equipment Diagnostics (First Cut Proof Of Concept) #41

Closed HyperActiveJ closed 2 years ago

HyperActiveJ commented 2 years ago

Proof of concept data diagnostic data collection for Indoor/Outdoor equipment units only, in a non-system specific manner (ie adaptable to differing hardware, self discovering, auto-generating)

Does not include S30/E30/Hub diagnostics (WIFI diagnostics). Also does not include zone diagnostic information. Both can be added...

First cut, could use some cleanup.

Pairs with corresponding lennoxs30 homeassistant integration pair request.

PeteRager commented 2 years ago

The key thing I’d like to add is tests. I’ve been doing this for all new stuff.

There are a number of examples in the tests directory. Basically we’d bootstrap the API by loading config, then feed the test messages (json files) and verify in the tests that the diagnostic attributes from the message are captured and that notifications are sent.

Here’s an example from test_mutations.py


def test_smart_away_mutations():
    api = setup_load_configuration()
    system = api.getSystem("0000000-0000-0000-0000-000000000001")
    assert system.sa_enabled == True
    assert system.sa_reset == False
    assert system.sa_cancel == False
    assert system.sa_state == LENNOX_SA_STATE_ENABLED_CANCELLED
    assert system.sa_setpointState == LENNOX_SA_SETPOINT_STATE_HOME
    data = loadfile("sa_config_cancel.json")
    api.processMessage(data)
    assert system.sa_enabled == True
    assert system.sa_reset == False
    assert system.sa_cancel == True
    assert system.sa_state == LENNOX_SA_STATE_ENABLED_CANCELLED
    assert system.sa_setpointState == LENNOX_SA_SETPOINT_STATE_HOME
` ` `

You’d capture diagnostic messages in one or more files.  The only trick is to then edit and put the system Id in the sender Id.
HyperActiveJ commented 2 years ago

I'm stuck home sick and finally have time to get back to this. I'm staring at the test examples and I'm afraid my mind has gone to mush, possibly the cold meds.

If you could get me started I'd like to help. I think you might be able to just crank it out while it might take me a couple tries.

The file "equipment_responce_energy.json" covers all the equipment diagnostics info as far as I can tell, I don't think you need a new capture.

test_diagnostic_responce.py looks like the place to start, but because there are about 80 or so sensors being created, I'm not really sure how to write an equivalent to cover all of them that also isn't a mess.

Let me know, I think you will find this data really interesting and useful. Because its self configuring I think it will give some insight into the various systems out there without so much hard coding everywhere.

Have you tried this out to see if it works for you?

PeteRager commented 2 years ago

Hope you feel better. I can take a look at getting the tests setup. Haven’t had a chance to run this yet, been a bunch of feature requests and bugs…anyways should have some time this upcoming week. Also I captured a message that appears to show the connection to the Cloud Relay Server, so we can use this to log a warning as people seem to get into trouble using diagnostics when there S30 is not firewalled off.

PeteRager commented 2 years ago

I wrote a unit test, I can't commit to your repo/branch can you add permissions?

PeteRager commented 2 years ago

Going out for a bit, here the test function that I added to the existing test_diagnostic_reponse.py

def test_process_diagnostics():
    api = setup_load_configuration()
    lsystem: lennox_system = api.getSystems()[0]
    assert len(lsystem.diagnosticPaths) == 0
    assert len(lsystem.diagnostics) == 0

    file_path = os.path.join(script_dir, "equipments_response_energy.json")
    with open(file_path) as f:
        data = json.load(f)
    api.processMessage(data)

    # It appears that only the power inverted diagnostics are captured in here
    # and the other diagnostics are not stored and only provided via callbacks.
    assert len(lsystem.diagnosticPaths) == 2
    assert len(lsystem.diagnostics) == 3

    assert len(lsystem.diagnostics[0]) == 1
    assert len(lsystem.diagnostics[1]) == 23
    assert len(lsystem.diagnostics[2]) == 24

    eq1 = lsystem.diagnostics[1]
    assert len(eq1) == 23

    eq_did = eq1[0]
    assert eq_did["name"] == "Comp. Short Cycle Delay Active"
    assert eq_did["unit"] == ""
    assert eq_did["value"] == "No"

    eq_did = eq1[1]
    assert eq_did["name"] == "Cooling Rate"
    assert eq_did["unit"] == "%"
    assert eq_did["value"] == "0.0"

    eq_did = eq1[2]
    assert eq_did["name"] == "Heating Rate"
    assert eq_did["unit"] == "%"
    assert eq_did["value"] == "0.0"

    eq_did = eq1[3]
    assert eq_did["name"] == "Compressor Shift Delay Active"
    assert eq_did["unit"] == ""
    assert eq_did["value"] == "No"

    eq_did = eq1[4]
    assert eq_did["name"] == "Defrost Status"
    assert eq_did["unit"] == ""
    assert eq_did["value"] == "Off"

    eq_did = eq1[9]
    assert eq_did["name"] == "Liquid Line Temp"
    assert eq_did["unit"] == "F"
    assert eq_did["value"] == "64.3"

    eq_did = eq1[22]
    assert eq_did["name"] == "Compressor Current"
    assert eq_did["unit"] == "A"
    assert eq_did["value"] == "0.000"

    #### Repeat for equipment 2
HyperActiveJ commented 2 years ago

You should have an invite to edit the repo