kizniche / Mycodo

An environmental monitoring and regulation system
http://kylegabriel.com/projects/
GNU General Public License v3.0
2.95k stars 494 forks source link

upgrade to 8.8.0, then 8.8.1, PCF8574 module fails to install and breaks installation #840

Closed ticomyco closed 4 years ago

ticomyco commented 4 years ago

**I saw your comment about releasing 8.8.0 for the multichannel outputs, and I upgraded my test system from 8.7.2 to 8.8.0, and then as soon as it finished I noticed that you'd released 8.8.1 so I upgraded again.

-- Same system as before -- RPi 4 with latest raspbian and the Krida relay board using the PCF8574 chip connected.

Last lines of mycodo.log are:

2020-09-09 09:52:19,943 - ERROR - mycodo.utils.outputs - Error: Cannot add output modules because it does not have a unique name: PCF8574
2020-09-09 09:52:19,953 - INFO - mycodo.outputs.on_off_shell_8b5fa089 - Initialized in 57.4 ms
2020-09-09 09:52:19,954 - INFO - mycodo.controllers.controller_output - Activated in 557.8 ms
2020-09-09 09:52:19,954 - ERROR - mycodo.controllers.controller_output - loop() Error
Traceback (most recent call last):
  File "/var/mycodo-root/mycodo/controllers/base_controller.py", line 84, in run
    self.loop()
  File "/var/mycodo-root/mycodo/controllers/controller_output.py", line 104, in loop
    self.output[output_id].output_on_until[each_channel] < datetime.datetime.now() and
KeyError: 0
2020-09-09 09:52:20,005 - ERROR - mycodo.controllers.controller_output - loop() Error
Traceback (most recent call last):
  File "/var/mycodo-root/mycodo/controllers/base_controller.py", line 84, in run
    self.loop()

(which then repeat a few thousand times)

and I've attached the mycodoupgrade.log file as well. It looks like there's a naming conflict with the PCF8574 module but I'm not sure what to do about it (such as trying to delete any configured outputs for example) because the webserver gives a 500 error with the following output when I try to load the login page, any dashboard, etc:

Error (Full Traceback):

Traceback (most recent call last):
  File "/home/pi/Mycodo/env/lib/python3.7/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/pi/Mycodo/env/lib/python3.7/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/pi/Mycodo/env/lib/python3.7/site-packages/flask_restx/api.py", line 639, in error_router
    return original_handler(e)
  File "/home/pi/Mycodo/env/lib/python3.7/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/pi/Mycodo/env/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/home/pi/Mycodo/env/lib/python3.7/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/pi/Mycodo/env/lib/python3.7/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/pi/Mycodo/env/lib/python3.7/site-packages/flask_login/utils.py", line 272, in decorated_view
    return func(*args, **kwargs)
  File "/home/pi/Mycodo/mycodo/mycodo_flask/routes_page.py", line 716, in page_dashboard
    output, OutputChannel, dict_outputs, dict_units, dict_measurements)
  File "/home/pi/Mycodo/mycodo/mycodo_flask/utils/utils_general.py", line 764, in choices_outputs_channels_measurements
    choices, each_output, output_channels, dict_outputs, dict_units, dict_measurements)
  File "/home/pi/Mycodo/mycodo/mycodo_flask/utils/utils_general.py", line 1011, in form_output_channel_measurement_choices
    measurement_channels = dict_outputs[each_output.output_type]['channels_dict'][each_channel.channel]['measurements']
KeyError: 'channels_dict'

mycodoupgrade.log**

ticomyco commented 4 years ago

Also, I didn't think this would fix anything, but for completeness' sake I did already try restarting the mycodoflask service (and then also tried restarting the Pi altogether) with no difference in results.

kizniche commented 4 years ago

Try a fresh install. I know we've been doing things to your install for this multi-channel system, so I would try from a fresh start. All my systems upgraded fine, no issues other than the few bugs fixed in 8.8.1.

ticomyco commented 4 years ago

Also I've noticed that these last log file entries in mycodo.log are repeating about 20x per second, and so the log files are growing to 20M and being rotated very quickly.

ticomyco commented 4 years ago

Ok, will give a fresh install a shot.

kizniche commented 4 years ago

log files are growing to 20M and being rotated very quickly

Definitely not a new feature 😬

ticomyco commented 4 years ago

log files are growing to 20M and being rotated very quickly

Definitely not a new feature grimacing

Haha -- yeah, I didn't think so :P Anyhow, fresh install is in process currently.

Btw, I see that the new PCF8574 module uses a DB read to get json data for the channel states instead of the lock file that was tested out in an earlier version,

output_channels = db_retrieve_table_daemon( OutputChannel).filter(OutputChannel.output_id == output.unique_id).all() self.options_channels = self.setup_custom_channel_options_json( OUTPUT_INFORMATION['custom_channel_options'], output_channels)

but also that in the IOPort class that it appears to read the state from the pcf8574 bus itself (which as we found, will not work when that chip is configured as an output for relay drivers):

state = self.pcf8574.bus.read_byte(self.pcf8574.address)

I'm still not very conversant in Python these days so I'm very likely missing something obvious, but I was thinking again about porting my MCP230xx bash scripts to python modules if I get some downtime, but I wanted to make sure I understood how the PCF8574 module worked first before hitting my head against the wall a bit, especially since the MCP chips do allow output state to be read directly from the chip.

kizniche commented 4 years ago

Okay. I might not have used the latest version we tested. I'll take a closer look.

ticomyco commented 4 years ago

Another issue -- I've just gotten up on a fresh install -- no other outputs or data sources configured yet -- I add the PCF8574 output module with the correct I2C bus/address, and I am able to enable/disable channel 1 successfully, however trying to enable/disable any other channel fails. In the web interface I'll get the blue notification pop up saying it's turning on (or off) an output, and then just below it a red notification pop up that gives no information other than "object object" as below, and no new entries in mycodo.log even with debug enabled. (however, modifying channel 1 does work and generate log file entries in debug mode).

Command sent to turn output f3c51283-93b9-40b9-a1e4-77a0de8164b5 On Output f3c51283-93b9-40b9-a1e4-77a0de8164b5: [object Object]

Output f3c51283-93b9-40b9-a1e4-77a0de8164b5: [object Object]

ticomyco commented 4 years ago

2020-09-09 10:53:12,249 - INFO - mycodo.outputs.pcf8574_f3c51283 - Initialized in 54.3 ms 2020-09-09 10:53:22,779 - DEBUG - mycodo.outputs.pcf8574_f3c51283 - output_on_off(on, 0, sec, 0.0, 0.0, True) 2020-09-09 10:53:22,780 - DEBUG - mycodo.outputs.pcf8574_f3c51283 - Output f3c51283-93b9-40b9-a1e4-77a0de8164b5 CH0 (Name) ON at 2020-09-09 10:53:22.779520. Output returned: success 2020-09-09 10:53:26,909 - DEBUG - mycodo.outputs.pcf8574_f3c51283 - output_on_off(off, 0, None, 0.0, 0.0, True) 2020-09-09 10:53:26,909 - DEBUG - mycodo.outputs.pcf8574_f3c51283 - Output f3c51283-93b9-40b9-a1e4-77a0de8164b5 CH0 (Name) OFF at 2020-09-09 10:53:26. Output returned: success

ticomyco commented 4 years ago

I've sent you login credentials via your contact page in case that could be helpful.

kizniche commented 4 years ago

the IOPort class that it appears to read the state from the pcf8574

I just had a chance to look at the module. Yes, this function exists in the class, but this function is not used. I should remove it. If you look at is_on(), you'll see it references self.output_states, which is a list of the states of each output channel.

ticomyco commented 4 years ago

Yes, this function exists in the class, but this function is not used. I should remove it. If you look at is_on(), you'll see it references self.output_states, which is a list of the states of each output channel.

I see that. Thanks for pointing that out. Do you get the same error with the PCF8574 module in 8.8.1 as I do? I'm wondering if reinstalled mycodo environment is to blame? I moved the old ~/Mycodo directory to a backup and started with a fresh git clone.

kizniche commented 4 years ago

I just fixed the bug that didn't allow turning on/off any channel except the first, and updated the module to more logically handle the startup/shutdown state. You can upgrade to master to test the changes.

kizniche commented 4 years ago

Okay, just killed the last bug (I think). Make sure you're on at least d6d2424 to have the latest working module.

kizniche commented 4 years ago

Alright, I need to redo the output page on/off button function. I introduced a huge bug trying to fix the multi-channel outputs. You can still test the new module, which should be unaffected.

ticomyco commented 4 years ago

Okay -- I just started an upgrade to master a few seconds ago -- we'll see. With regards to the huge bug you just mentioned affecting on/off buttons, will I need to use another method to test the pcf8574 module in the meantime?

kizniche commented 4 years ago

No, just don't test anything other than the PCF8574

ticomyco commented 4 years ago

upgraded to master, now I get the same error (the "object object" message) when trying to enable disable any channel, including channel 0 / channel 1.

No new entries in mycodo.log, have also tried deleting the pcf8574 output and recreating it with debug enabled, same results.

kizniche commented 4 years ago

I just pushed a fix for the entire web interface output control... try upgrading to master again and see if it all works.

ticomyco commented 4 years ago

Command sent to turn output 897838c8-88de-438a-9fee-6d53fb324e1e On Output 897838c8-88de-438a-9fee-6d53fb324e1e: [object Object] ^--- The error I was getting.

Just saw your update, upgrading to master again right now.

ticomyco commented 4 years ago

Now I don't get the error messages on the web interface, however I still don't get any change in output relay state when trying any channels on the pcf8574.

I also tried deleting the output and adding it again fresh. log entries: 2020-09-09 13:40:51,033 - INFO - mycodo.outputs.pcf8574_897838c8 - Stopped in 0.1 ms 2020-09-09 13:41:02,226 - INFO - mycodo.outputs.pcf8574_1109b9b8 - Initialized in 52.0 ms 2020-09-09 13:41:34,973 - INFO - mycodo.outputs.pcf8574_1109b9b8 - Initialized in 56.5 ms 2020-09-09 13:41:49,315 - DEBUG - mycodo.outputs.pcf8574_1109b9b8 - output_on_off(on, 0, sec, 0.0, 0.0, True) 2020-09-09 13:41:49,316 - DEBUG - mycodo.outputs.pcf8574_1109b9b8 - Output 1109b9b8-2ba9-47a2-8c37-bad28bb3cb37 CH0 (test3) ON at 2020-09-09 13:41:49.316288. Output returned: success 2020-09-09 13:41:53,276 - DEBUG - mycodo.outputs.pcf8574_1109b9b8 - output_on_off(off, 0, None, 0.0, 0.0, True) 2020-09-09 13:41:53,277 - DEBUG - mycodo.outputs.pcf8574_1109b9b8 - Output 1109b9b8-2ba9-47a2-8c37-bad28bb3cb37 CH0 (test3) OFF at 2020-09-09 13:41:53. Output returned: success 2020-09-09 13:41:58,188 - DEBUG - mycodo.outputs.pcf8574_1109b9b8 - output_on_off(on, 2, sec, 0.0, 0.0, True) 2020-09-09 13:41:58,189 - ERROR - mycodo.outputs.pcf8574_1109b9b8 - CH2 state change error: 0 2020-09-09 13:41:58,189 - DEBUG - mycodo.outputs.pcf8574_1109b9b8 - Output 1109b9b8-2ba9-47a2-8c37-bad28bb3cb37 CH2 (test3) ON at 2020-09-09 13:41:58.188788. Output returned: CH2 state change error: 0 2020-09-09 13:42:06,103 - DEBUG - mycodo.outputs.pcf8574_1109b9b8 - output_on_off(off, 2, None, 0.0, 0.0, True) 2020-09-09 13:42:06,103 - ERROR - mycodo.outputs.pcf8574_1109b9b8 - CH2 state change error: 0 2020-09-09 13:42:06,104 - DEBUG - mycodo.outputs.pcf8574_1109b9b8 - Output 1109b9b8-2ba9-47a2-8c37-bad28bb3cb37 CH2 (test3) OFF at 2020-09-09 13:42:06. Output returned: CH2 state change error: 0

EDIT: Also, I just doublechecked using my bash scripts that the Krida relay board still responds correctly over I2C.

kizniche commented 4 years ago

I just pushed a fix that should make it work

ticomyco commented 4 years ago

Sweet. upgrading now.

kizniche commented 4 years ago

Perhaps i'm misinterpreting how the class I added works. let me review the example from the original code.

kizniche commented 4 years ago

I did tear apart the PCF8574 class, but I think I still preserved functionality. The latest update might have fixed the issue in previous versions.

ticomyco commented 4 years ago

Sorry -- it looks like this update still results in the same problems, even after deleting and re-adding the output -- no relay states are changed succesffully: 2020-09-09 13:57:56,279 - INFO - mycodo.outputs.pcf8574_dafe6b18 - Initialized in 51.8 ms 2020-09-09 13:58:00,718 - DEBUG - mycodo.outputs.pcf8574_dafe6b18 - output_on_off(on, 0, sec, 0.0, 0.0, True) 2020-09-09 13:58:00,718 - ERROR - mycodo.outputs.pcf8574_dafe6b18 - CH0 state change error: 2020-09-09 13:58:00,719 - DEBUG - mycodo.outputs.pcf8574_dafe6b18 - Output dafe6b18-2c87-4e58-afc9-9ed654363f89 CH0 (test4) ON at 2020-09-09 13:58:00.718537. Output returned: CH0 state change error: 2020-09-09 13:58:05,105 - DEBUG - mycodo.outputs.pcf8574_dafe6b18 - output_on_off(off, 0, None, 0.0, 0.0, True) 2020-09-09 13:58:05,105 - ERROR - mycodo.outputs.pcf8574_dafe6b18 - CH0 state change error: 2020-09-09 13:58:05,106 - DEBUG - mycodo.outputs.pcf8574_dafe6b18 - Output dafe6b18-2c87-4e58-afc9-9ed654363f89 CH0 (test4) OFF at 2020-09-09 13:58:05. Output returned: CH0 state change error: 2020-09-09 13:58:13,497 - DEBUG - mycodo.outputs.pcf8574_dafe6b18 - output_on_off(on, 6, sec, 0.0, 0.0, True) 2020-09-09 13:58:13,498 - ERROR - mycodo.outputs.pcf8574_dafe6b18 - CH6 state change error: 0 2020-09-09 13:58:13,498 - DEBUG - mycodo.outputs.pcf8574_dafe6b18 - Output dafe6b18-2c87-4e58-afc9-9ed654363f89 CH6 (test4) ON at 2020-09-09 13:58:13.498347. Output returned: CH6 state change error: 0 2020-09-09 13:58:17,505 - DEBUG - mycodo.outputs.pcf8574_dafe6b18 - output_on_off(off, 6, None, 0.0, 0.0, True) 2020-09-09 13:58:17,506 - ERROR - mycodo.outputs.pcf8574_dafe6b18 - CH6 state change error: 0 2020-09-09 13:58:17,507 - DEBUG - mycodo.outputs.pcf8574_dafe6b18 - Output dafe6b18-2c87-4e58-afc9-9ed654363f89 CH6 (test4) OFF at 2020-09-09 13:58:17. Output returned: CH6 state change error: 0

kizniche commented 4 years ago

Can you isolate this code to a new file and test it by itself and perhaps see what's wrong with it?

https://github.com/kizniche/Mycodo/blob/5aa234289ec93a14c5d8f344b54e3194cf9af9a8/mycodo/outputs/pcf8574.py#L307-L325

kizniche commented 4 years ago

It should now work by supplying a list:

import time
import smbus2

bus = 1
address = "0x20"
sensor = PCF8574(smbus2, bus, int(str(address), 16))

states = [False, False, False, False, False, False, False, False]
sensor.port(states)

time.sleep(5)

states = [True, False, False, False, False, False, False, False]
sensor.port(states)

class PCF8574(object):
    """ A software representation of a single PCF8574 IO expander chip """
    def __init__(self, smbus, i2c_bus, i2c_address):
        self.bus_no = i2c_bus
        self.bus = smbus.SMBus(i2c_bus)
        self.address = i2c_address

    def __repr__(self):
        return "PCF8574(i2c_bus_no=%r, address=0x%02x)" % (self.bus_no, self.address)

    def port(self, value):
        """ Set the whole port using a list """
        assert isinstance(value, list)
        assert len(value) == 8
        new_state = 0
        for i, val in enumerate(value):
            if val:
                new_state |= 1 << i
        self.bus.write_byte(self.address, new_state)
kizniche commented 4 years ago

I can always revert back to the original code, but I'd like to remove the query sections because they didn't work and only keep the write sections.

kizniche commented 4 years ago

I also just pushed a commit with debug lines so you can see the list being sent to the port() function. Make sure Log Level Debug is enabled for the output.

kizniche commented 4 years ago

Oh, I see I'm not setting up the self.sensor device properly! one second and I'll have another potential fix.

Edit: nevermind. That was a dead end. I did just push another commit with a debug line for the I2C address and bus to just to verify that's going through correctly.

ticomyco commented 4 years ago

I was just about to say -- I got: Mycodo/env/bin/python3.7 ./kridatest3.py Traceback (most recent call last): File "./kridatest3.py", line 7, in self.sensor = PCF8574(smbus2, bus, int(str(address), 16)) TypeError: init() takes 3 positional arguments but 4 were given

after also adding "from pcf8574 import PCF8574" and also getting pip to install the pcf8574 module (which apparently wasn't autoinstalled in the mycodo environment when I'd upgraded and re-added the module..)

ticomyco commented 4 years ago

okay, upgrading again now.

kizniche commented 4 years ago

Don't install the pcf module from pypi, it's included at the bottom of the output module.

kizniche commented 4 years ago

self.sensor = PCF8574(smbus2, bus, int(str(address), 16)) TypeError: init() takes 3 positional arguments but 4 were given

This doesn't make any sense. You can clearly see there are only 3 arguments given to initialize the class.

kizniche commented 4 years ago

Here, put the class before everything:

import time
import smbus2

class PCF8574(object):
    """ A software representation of a single PCF8574 IO expander chip """
    def __init__(self, smbus, i2c_bus, i2c_address):
        self.bus_no = i2c_bus
        self.bus = smbus.SMBus(i2c_bus)
        self.address = i2c_address

    def __repr__(self):
        return "PCF8574(i2c_bus_no=%r, address=0x%02x)" % (self.bus_no, self.address)

    def port(self, value):
        """ Set the whole port using a list """
        assert isinstance(value, list)
        assert len(value) == 8
        new_state = 0
        for i, val in enumerate(value):
            if val:
                new_state |= 1 << i
        self.bus.write_byte(self.address, new_state)

bus = 1
address = "0x20"
sensor = PCF8574(smbus2, bus, int(str(address), 16))

states = [False, False, False, False, False, False, False, False]
sensor.port(states)

time.sleep(5)

states = [True, False, False, False, False, False, False, False]
sensor.port(states)
ticomyco commented 4 years ago

I agree, however I just copied and pasted your code (aside from changing the bus# and I2C address) and ran it as follows: pi@raspmush2:~ $ Mycodo/env/bin/python3.7 ./kridatest3.py Traceback (most recent call last): File "./kridatest3.py", line 6, in self.sensor = PCF8574(smbus2, bus, int(str(address), 16)) NameError: name 'PCF8574' is not defined

Then, I tried adding the "from pcf8574 import PCF8574" line as I mentioned before, and then I got the following output: pi@raspmush2:~ $ Mycodo/env/bin/python3.7 ./kridatest3.py Traceback (most recent call last): File "./kridatest3.py", line 7, in self.sensor = PCF8574(smbus2, bus, int(str(address), 16)) TypeError: init() takes 3 positional arguments but 4 were given

kizniche commented 4 years ago

self.sensor = PCF8574(smbus2, bus, int(str(address), 16))

There should not be "self"

Make sure you're using the exact code I have in the comment.

ticomyco commented 4 years ago

Okay, just ran the most recent code you provided -- runs without errors, and results in all outputs off, and then just the first channel on.

I also tried changing some of the False's to True's and vice versa, and the board responds as expected with this code.

kizniche commented 4 years ago

Strange. It's the exact same code from the module. Can you run the latest module with the debug lines and see what the lists being passed to self.sensor.port() are?

ticomyco commented 4 years ago

self.sensor = PCF8574(smbus2, bus, int(str(address), 16))

There should not be "self"

Make sure you're using the exact code I have in the comment.

Sorry -- that response was when I was running the code you'd provided in https://github.com/kizniche/Mycodo/issues/840#issuecomment-689756851

My most recent comment reflects running the most recent code that you provided.

ticomyco commented 4 years ago

Okay, running latest code -- with the existing output still setup, I tried enabling/disabling a channel and got the following log entries: 2020-09-09 14:25:28,783 - DEBUG - mycodo.outputs.pcf8574_dafe6b18 - output_on_off(on, 3, sec, 0.0, 0.0, True) 2020-09-09 14:25:28,784 - ERROR - mycodo.outputs.pcf8574_dafe6b18 - CH3 state change error: 0 2020-09-09 14:25:28,784 - DEBUG - mycodo.outputs.pcf8574_dafe6b18 - Output dafe6b18-2c87-4e58-afc9-9ed654363f89 CH3 (test4) ON at 2020-09-09 14:25:28.784346. Output returned: CH3 state change error: 0 2020-09-09 14:25:48,615 - DEBUG - mycodo.outputs.pcf8574_dafe6b18 - output_on_off(off, 3, None, 0.0, 0.0, True) 2020-09-09 14:25:48,616 - ERROR - mycodo.outputs.pcf8574_dafe6b18 - CH3 state change error: 0 2020-09-09 14:25:48,616 - DEBUG - mycodo.outputs.pcf8574_dafe6b18 - Output dafe6b18-2c87-4e58-afc9-9ed654363f89 CH3 (test4) OFF at 2020-09-09 14:25:48. Output returned: CH3 state change error: 0

then I tried deleting the output, and upon re-adding it, I got a yellow pop-up with the error: "Error: Add Output: Daemon response: add_mod_output() Error: 720cdb9f-b3e4-426f-af11-a59a308f98fd: [Errno 121] Remote I/O error"

Subsequently, configuring the new output bus and i2c address results in any of the already-enabled relays to be disabled (as expected since they're all supposed to be disabled by default), however enabling/disabling any relay channel has no effect: 2020-09-09 14:26:47,991 - DEBUG - mycodo.outputs.pcf8574_dafe6b18 - List sent to device: [False, False, False, False, False, False, False, False] 2020-09-09 14:26:47,992 - INFO - mycodo.outputs.pcf8574_dafe6b18 - Stopped in 1.1 ms 2020-09-09 14:28:47,338 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - I2C: Address: 0x26, Bus: 19 2020-09-09 14:28:47,339 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - List sent to device: [False, False, False, False, False, False, False, False] 2020-09-09 14:28:47,340 - INFO - mycodo.outputs.pcf8574_720cdb9f - Initialized in 71.1 ms 2020-09-09 14:28:57,482 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - output_on_off(on, 1, sec, 0.0, 0.0, True) 2020-09-09 14:28:57,483 - ERROR - mycodo.outputs.pcf8574_720cdb9f - CH1 state change error: 0 2020-09-09 14:28:57,484 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - Output 720cdb9f-b3e4-426f-af11-a59a308f98fd CH1 (test5) ON at 2020-09-09 14:28:57.483008. Output returned: CH1 state change error: 0 2020-09-09 14:29:03,978 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - output_on_off(off, 1, None, 0.0, 0.0, True) 2020-09-09 14:29:03,978 - ERROR - mycodo.outputs.pcf8574_720cdb9f - CH1 state change error: 0 2020-09-09 14:29:03,979 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - Output 720cdb9f-b3e4-426f-af11-a59a308f98fd CH1 (test5) OFF at 2020-09-09 14:29:03. Output returned: CH1 state change error: 0

kizniche commented 4 years ago

Change "error" to "exception", restart the daemon, and it will show the full traceback:

https://github.com/kizniche/Mycodo/blob/90a355ecf258078c8ccb188f1ab04a49a16a7d8e/mycodo/outputs/pcf8574.py#L277

kizniche commented 4 years ago

The good news is we know the class is working because it turned everything off when it initialized and sent the initial list filled with False, as indicated from the debug line.

kizniche commented 4 years ago

Before we get the full traceback, it may be that one or more of your channels don't have On State set (for some reason), so make sure all options are set for each channel.

ticomyco commented 4 years ago

Gotcha. Made the edit, checked that all channel outputs have their "on state" set to the default of HIGH.

enabling/disabling the first channel gives: 2020-09-09 15:06:58,694 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - output_on_off(on, 0, sec, 0.0, 0.0, True) 2020-09-09 15:06:58,694 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - List sent to device: [True] 2020-09-09 15:06:58,694 - ERROR - mycodo.outputs.pcf8574_720cdb9f - CH0 state change error: Traceback (most recent call last): File "/home/pi/Mycodo/mycodo/outputs/pcf8574.py", line 272, in output_switch self.sensor.port(self.dict_to_list_states(dict_states)) File "/home/pi/Mycodo/mycodo/outputs/pcf8574.py", line 324, in port assert len(value) == 8 AssertionError 2020-09-09 15:06:58,695 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - Output 720cdb9f-b3e4-426f-af11-a59a308f98fd CH0 (test5) ON at 2020-09-09 15:06:58.694633. Output returned: CH0 state change error: 2020-09-09 15:07:14,564 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - output_on_off(off, 0, None, 0.0, 0.0, True) 2020-09-09 15:07:14,564 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - List sent to device: [False] 2020-09-09 15:07:14,565 - ERROR - mycodo.outputs.pcf8574_720cdb9f - CH0 state change error: Traceback (most recent call last): File "/home/pi/Mycodo/mycodo/outputs/pcf8574.py", line 272, in output_switch self.sensor.port(self.dict_to_list_states(dict_states)) File "/home/pi/Mycodo/mycodo/outputs/pcf8574.py", line 324, in port assert len(value) == 8 AssertionError 2020-09-09 15:07:14,565 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - Output 720cdb9f-b3e4-426f-af11-a59a308f98fd CH0 (test5) OFF at 2020-09-09 15:07:14. Output returned: CH0 state change error:

ticomyco commented 4 years ago

Just for grins, (with all channels set to off in Mycodo and also off on the relay board), I changed the "on state" for only the first channel to be LOW instead of HIGH. I saved the settings and immediately the first channel on the krida board was enabled with all others disabled, and in the Mycodo interface that channel immediately turned green and indicated and active state.

However, as with the previous test in my last comment, attempting to enable/disable the channel had no effect on the output, and also did not update the web interface to reflect anything other than the initial active state that occurred as soon as I saved that setting.

2020-09-09 15:09:28,581 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - I2C: Address: 0x26, Bus: 19 2020-09-09 15:09:28,581 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - List sent to device: [True, False, False, False, False, False, False, False] 2020-09-09 15:09:28,582 - INFO - mycodo.outputs.pcf8574_720cdb9f - Initialized in 70.2 ms 2020-09-09 15:10:23,166 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - output_on_off(off, 0, None, 0.0, 0.0, True) 2020-09-09 15:10:23,167 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - List sent to device: [True] 2020-09-09 15:10:23,167 - ERROR - mycodo.outputs.pcf8574_720cdb9f - CH0 state change error: Traceback (most recent call last): File "/home/pi/Mycodo/mycodo/outputs/pcf8574.py", line 272, in output_switch self.sensor.port(self.dict_to_list_states(dict_states)) File "/home/pi/Mycodo/mycodo/outputs/pcf8574.py", line 324, in port assert len(value) == 8 AssertionError 2020-09-09 15:10:23,168 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - Output 720cdb9f-b3e4-426f-af11-a59a308f98fd CH0 (test5) OFF at 2020-09-09 15:10:23. Output returned: CH0 state change error: 2020-09-09 15:10:28,758 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - output_on_off(on, 0, sec, 0.0, 0.0, True) 2020-09-09 15:10:28,758 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - Output 720cdb9f-b3e4-426f-af11-a59a308f98fd CH0 (test5) is already on. 2020-09-09 15:10:35,067 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - output_on_off(off, 0, None, 0.0, 0.0, True) 2020-09-09 15:10:35,067 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - List sent to device: [True] 2020-09-09 15:10:35,068 - ERROR - mycodo.outputs.pcf8574_720cdb9f - CH0 state change error: Traceback (most recent call last): File "/home/pi/Mycodo/mycodo/outputs/pcf8574.py", line 272, in output_switch self.sensor.port(self.dict_to_list_states(dict_states)) File "/home/pi/Mycodo/mycodo/outputs/pcf8574.py", line 324, in port assert len(value) == 8 AssertionError 2020-09-09 15:10:35,069 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - Output 720cdb9f-b3e4-426f-af11-a59a308f98fd CH0 (test5) OFF at 2020-09-09 15:10:35. Output returned: CH0 state change error: 2020-09-09 15:10:41,880 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - output_on_off(on, 0, sec, 0.0, 0.0, True) 2020-09-09 15:10:41,880 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - Output 720cdb9f-b3e4-426f-af11-a59a308f98fd CH0 (test5) is already on.

ticomyco commented 4 years ago

I suspect that because having an output (transistor, SSR, relay coil, etc) attached to the IO pin of the pcf8574 effectively pulls it low such that a request to read the state of that pin as an input will always report it as low, regardless of whether the pin output has been configured high or not, that possibly the code is still attempting to read the state from the chip somewhere when attempting to enable disable individual outputs, but not when initializing?

kizniche commented 4 years ago

If we analyze the log output, we first see:

2020-09-09 15:06:58,694 - DEBUG - mycodo.outputs.pcf8574_720cdb9f - List sent to device: [True]

This indicates there's an issue with generating the full list of states. Indeed, We aren't generating the full list, but merely a list of just the channel that changed. The next line of interest is:

2020-09-09 15:10:23,167 - ERROR - mycodo.outputs.pcf8574_720cdb9f - CH0 state change error:
Traceback (most recent call last):
File "/home/pi/Mycodo/mycodo/outputs/pcf8574.py", line 272, in output_switch
self.sensor.port(self.dict_to_list_states(dict_states))
File "/home/pi/Mycodo/mycodo/outputs/pcf8574.py", line 324, in port
assert len(value) == 8
AssertionError

This also indicates the list does not have a length of 8. I will push a fix in a moment that will generate the full list. This was a dumb mistake. It looks obvious now that I see the debug logs.

possibly the code is still attempting to read the state from the chip somewhere when attempting to enable disable individual outputs

This is an impossibility. All output states are stored and queried from the self.output_states dictionary.

kizniche commented 4 years ago

The commit I just pushed should finally fix the output!