Harsch-Systems / node-red-contrib-pi-plates

Control Pi-Plates from Node-RED
Apache License 2.0
6 stars 7 forks source link

RELAYplate Not Working #5

Open BBQRules opened 4 years ago

BBQRules commented 4 years ago

I set up a Pi with Buster Lite and a RELAYplate. I have SPI running and python 2.7.

Triggering the relays using the python commands on the RELAYplate website works without issue.

If I add the RELAYplate to Node-Red and use a "on" trigger, nothing happens.

Node-Red log shows:

pi@raspberrypi:~/.node-red $ node-red-log

RP.relayON(addr, relay)

File "/usr/local/lib/python2.7/dist-packages/piplates/RELAYplate.py", line 75, in relayON stderr: VerifyADDR(addr) File "/usr/local/lib/python2.7/dist-packages/piplates/RELAYplate.py", line 175, in VerifyADDR assert (relaysPresent[addr]==1),"No RELAYplate found at address "+addr_str AssertionError: No RELAYplate found at address 0 code: 1 signal: null

mharsch commented 4 years ago

The address that the error is referring to is the physical jumpers on the PiPlate (the plate address in the stack). Are you sure the configuration of the relay node matches the relay plate physical address (configured when you first add a PiPlate node)?

BBQRules commented 4 years ago

Thanks for your help with this Mike.

I was wondering the same thing but I'm pretty sure it's correct. The pi-plate is address 0 out of the box and I didn't change any jumpers.

From the Pi-Plates website I used these commands and it worked fine:

import piplates.RELAYplate as RELAY

RELAY.getID(0) 'Pi-Plate RELAY' RELAY.relayON(0,3)

I also tried setting up a number of triggers going into a number of pi-plate addresses with no switching as a result. You'll notice in the attached screen shot that the message coming from the top inject does not pass through the Plate0 node. [image: image.png]

The top relay node config:

[image: image.png]

[image: image.png]

On Thu, Aug 1, 2019 at 9:19 PM Mike Harsch notifications@github.com wrote:

The address that the error is referring to is the physical jumpers on the PiPlate (the plate address in the stack). Are you sure the configuration of the relay node matches the relay plate physical address (configured when you first add a PiPlate node)?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mharsch/node-red-contrib-pi-plates/issues/5?email_source=notifications&email_token=AMY2QOYY4MLP7RIF7OAXXI3QCOKUPA5CNFSM4IIYNWH2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3MMFTY#issuecomment-517522127, or mute the thread https://github.com/notifications/unsubscribe-auth/AMY2QO2WKZJNMHWGJQFA22TQCOKUPANCNFSM4IIYNWHQ .

mharsch commented 4 years ago

Ok, I've seen this symptom before, but I'd like to try to narrow it down. The error "AssertionError: No RELAYplate found at address 0" comes from python code running under the hood. If we can reproduce the problem with just a python program (without running any Node-RED at all) that will help us narrow down the issue. When I've seen this before, it happens more frequently when the system is under load (causing the python program to possibly be interrupted while it's doing SPI communication with the PiPlates). When Node-RED is starting up, the pi is under load and so that's why it happens more frequently for us. Anyway, could I ask you to write a python test program that toggles relays and loops forever, then run some other programs at the same time to put a load on the system? If I'm right, you'll be able to crash your python program with the same error (eventually).

mharsch commented 4 years ago

Ok, I think I see at least part of the problem here. You can't have plates configured with addresses that do not exist (e.g. a plate configured with address 1 when only a single plate with address 0 is installed). As soon as the underlying python script gets an incorrect address, it crashes and does not restart until the entire Node-RED service is restarted. So, the fix here is to remove all the configuration nodes for addresses that are not present, and then restart Node-RED (or reboot the whole pi) and try again. Let me know if this works. This is essentially a duplicate of issue #3

BBQRules commented 4 years ago

Gave it a try deleting the unused nodes and rebooted pi.

Same issue.

I'm working on the toggle test script now.

What would you suggest I run to ta the processor when the script is ready?

On Fri, Aug 2, 2019 at 8:50 AM Mike Harsch notifications@github.com wrote:

Ok, I think I see at least part of the problem here. You can't have plates configured with addresses that do not exist (e.g. a plate configured with address 1 when only a single plate with address 0 is installed). As soon as the underlying python script gets an incorrect address, it crashes and does not restart until the entire Node-RED service is restarted. So, the fix here is to remove all the configuration nodes for addresses that are not present, and then restart Node-RED (or reboot the whole pi) and try again. Let me know if this works.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mharsch/node-red-contrib-pi-plates/issues/5?email_source=notifications&email_token=AMY2QOYVPVYQYVRAD5DPPM3QCQ3S3A5CNFSM4IIYNWH2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3NZTKI#issuecomment-517708201, or mute the thread https://github.com/notifications/unsubscribe-auth/AMY2QO57WWSYOGBJIJAER6DQCQ3S3ANCNFSM4IIYNWHQ .

mharsch commented 4 years ago

Could you make sure that the "configuration nodes" associated with the non-existent plates are also removed? Check the 'configuration nodes' section in the right-hand pane then double click on any unused nodes and click 'delete'. Then reboot and re-test. Thanks.

BBQRules commented 4 years ago

Yup. Did that.

Still not working.

Sorry.

On Fri, Aug 2, 2019 at 11:33 AM Mike Harsch notifications@github.com wrote:

Could you make sure that the "configuration nodes" associated with the non-existent plates are also removed? Check the 'configuration nodes' section in the right-hand pane then double click on any unused nodes and click 'delete'. Then reboot and re-test. Thanks.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mharsch/node-red-contrib-pi-plates/issues/5?email_source=notifications&email_token=AMY2QO5FCMVPCLVEQQSWTGLQCROWZA5CNFSM4IIYNWH2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3OHXJY#issuecomment-517766055, or mute the thread https://github.com/notifications/unsubscribe-auth/AMY2QO6MXBM5SV6OLSMHAITQCROWZANCNFSM4IIYNWHQ .

BBQRules commented 4 years ago

So I retooled a script I got off YouTube. What would you suggest I do to burden the pi?

!/usr/bin/python

import piplates.RELAYplate as RELAY import time

relayList = [1, 2, 3, 4, 5, 6, 7]

for i in relayList: RELAY.relayOFF(0,1)

SleepTimeS = 0.05 SleepTimeL = 0.05

main loop

try: while True: for i in relayList: RELAY.relayOFF(0,i) time.sleep(SleepTimeS); RELAY.relayON(0,i) time.sleep(SleepTimeS); RELAY.relayOFF(0,i) time.sleep(SleepTimeS); RELAY.relayOFF(0,i) time.sleep(SleepTimeL);

End program cleanly with keyboard

except KeyboardInterrupt: print " Quit"

On Fri, Aug 2, 2019 at 11:33 AM Mike Harsch notifications@github.com wrote:

Could you make sure that the "configuration nodes" associated with the non-existent plates are also removed? Check the 'configuration nodes' section in the right-hand pane then double click on any unused nodes and click 'delete'. Then reboot and re-test. Thanks.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mharsch/node-red-contrib-pi-plates/issues/5?email_source=notifications&email_token=AMY2QO5FCMVPCLVEQQSWTGLQCROWZA5CNFSM4IIYNWH2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3OHXJY#issuecomment-517766055, or mute the thread https://github.com/notifications/unsubscribe-auth/AMY2QO6MXBM5SV6OLSMHAITQCROWZANCNFSM4IIYNWHQ .

BBQRules commented 4 years ago

This is my Node-Red setup at this stage:

[image: image.png]

On Fri, Aug 2, 2019 at 11:33 AM Mike Harsch notifications@github.com wrote:

Could you make sure that the "configuration nodes" associated with the non-existent plates are also removed? Check the 'configuration nodes' section in the right-hand pane then double click on any unused nodes and click 'delete'. Then reboot and re-test. Thanks.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mharsch/node-red-contrib-pi-plates/issues/5?email_source=notifications&email_token=AMY2QO5FCMVPCLVEQQSWTGLQCROWZA5CNFSM4IIYNWH2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3OHXJY#issuecomment-517766055, or mute the thread https://github.com/notifications/unsubscribe-auth/AMY2QO6MXBM5SV6OLSMHAITQCROWZANCNFSM4IIYNWHQ .

mharsch commented 4 years ago

Note: this issue originally presented while running on on a Raspberry Pi Model B. It can also be reproduced using a Pi Zero (which uses the same CPU). It's much easier to reproduce this on the slower CPU variants, because the root cause is sensitive to system load and Node-RED is fairly CPU intensive when starting up. The Node-RED Pi-Plates nodes have an underlying python process that is launched when Node-RED starts up. This process instantiates python objects that are used to send commands to the plate stack. At the time of initialization, the relay plate object scans the address range (0-8) for plates of type RELAYplate and keeps a table of discovered devices. If this scan fails to enumerate a plate (which can easily happen if the system is under load) then the state of the table that tracks relay plates present in the system will be incomplete (and will stay incorrect for the life of the process -- a long running process in this case). As soon as a command comes in for a plate that the underlying python object failed to initialize, the process crashes with the "No RELAYplate found at address " message. The fix here needs to be twofold: first we need to fix issue #3 so that the underlying python process can survive unexpected input. Second we need to get retry logic added upstream to the official Pi Plates code so that undiscovered plates can be picked up and used after they were missed during initialization.

PCRover commented 4 years ago

Did this issue get resolved? I appear to be experiencing the same problem with a Pi3 vB.

mharsch commented 4 years ago

No, this issue is still unresolved. If you could provide more details of your specific configuration, that would help. NodeRED version, pyplates (python package) version, which plates and how many are installed / jumper addresses. Is the problem intermittent or consistently repeatable for you?

DougSmythies commented 2 years ago

I have been working on this issue for a while, and found this posting. My findings are:

I use this script to get a large number of samples in a short time:

doug@rpi2:~ $ cat test-addr.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
#

import sys
import time
import piplates.RELAYplate as RELAY

from numpy import *
from decimal import *
getcontext().prec = 8

print('Test getADDR function. Smythies 2022.03.26. Updated 2022.04.30.')

n = int(sys.argv[1])

count=0
fails=0
old_fails=0

while True:
    loops=0
    while(loops<10000):
        rtn = RELAY.getADDR(n)
        if (rtn!=n):
            fails += 1
#            print("FAILS:%d  Loops:%d  return:%d" %(fails, count, rtn))
        count += 1
        loops += 1
    pct_fail = Decimal(100) * Decimal(fails) / Decimal(count)
    print("TOTAL FAILS:%d  Loops:%d  LAST FAILS:%d  Percent FAILS:%.6f" %(fails, count, (fails - old_fails), pct_fail))
    old_fails = fails

I am proposing this patch to Pi-Plates:

doug@rpi2:~ $ diff --unified /usr/local/lib/python2.7/dist-packages/piplates/RELAYplate.py.original /usr/local/lib/python2.7/dist-packages/piplates/RELAYplate.py
--- /usr/local/lib/python2.7/dist-packages/piplates/RELAYplate.py.original      2022-03-24 12:10:01.287226879 -0700
+++ /usr/local/lib/python2.7/dist-packages/piplates/RELAYplate.py       2022-05-03 07:29:31.031909693 -0700
@@ -199,6 +199,12 @@
     global RELAYbaseADDR
     resp = []
     resp=ppCMDr(addr,0x00,0,0,1)
+    #due to timing requirements that do not allow for ISR and other gaps, retry might be needed
+    if (resp[0]==0):
+        resp=ppCMDr(addr,0x00,0,0,1)
+        # one retry might not be enough
+        if (resp[0]==0):
+            resp=ppCMDr(addr,0x00,0,0,1)
     return resp[0]-RELAYbaseADDR

And got these test results:

mharsch commented 2 years ago

Thanks for sharing. /cc @pi-plates

DougSmythies commented 2 years ago

Mike, thank you for your reply. I see you copied Pi-Plates. Please be aware that I have been working with Pi-Plates support on this the whole time.