NodeRed und DIO
Sehr geehrte Community,
Ich habe auf der Supportseite des Revolution-Pi´s keine Lösung zum Thema fehlende Module bzw. Paletten für NodeRed finden können.
Mein derzeitiger Ansatz war es per piTest Abläufe und Verzweigungen hart zu coden um eine Abhängigkeit schaffen zu können.
Auf der Internetseite wird allerdings auch eine Palette für NodeRed gezeigt die ich gerne beziehen möchte.
Leider habe ich keine finden können und im Forum wurde ich diesbezüglich auch nicht fündig.
Ausgangssituation ist wie folgt:
Über ein Schlüsselschalter an Input_1 soll durch umschalten von 0 auf 1, eine logische 1 an den Output 1 gesendet werden.
über den Output_1 wiederrum soll ein SOAP-Request zu einer Telefonanlage gesendet werden, der die Rufumleitung auf diese Station umschaltet.
Wird der Schalter wieder auf 0 gestellt, soll diese Umleitung wieder deaktiviert werden.
Jeder Zustand soll durch je eine LED zusätzlich angezeigt werden.
Realisieren wollte ich diese Logik mit NodeRed da ich nicht so sehr der Programmierer bin.
Über eine Hilfestellung wäre ich sehr dankbar.
Ich habe auf der Supportseite des Revolution-Pi´s keine Lösung zum Thema fehlende Module bzw. Paletten für NodeRed finden können.
Mein derzeitiger Ansatz war es per piTest Abläufe und Verzweigungen hart zu coden um eine Abhängigkeit schaffen zu können.
Auf der Internetseite wird allerdings auch eine Palette für NodeRed gezeigt die ich gerne beziehen möchte.
Leider habe ich keine finden können und im Forum wurde ich diesbezüglich auch nicht fündig.
Ausgangssituation ist wie folgt:
Über ein Schlüsselschalter an Input_1 soll durch umschalten von 0 auf 1, eine logische 1 an den Output 1 gesendet werden.
über den Output_1 wiederrum soll ein SOAP-Request zu einer Telefonanlage gesendet werden, der die Rufumleitung auf diese Station umschaltet.
Wird der Schalter wieder auf 0 gestellt, soll diese Umleitung wieder deaktiviert werden.
Jeder Zustand soll durch je eine LED zusätzlich angezeigt werden.
Realisieren wollte ich diese Logik mit NodeRed da ich nicht so sehr der Programmierer bin.
Über eine Hilfestellung wäre ich sehr dankbar.
hi Joey,
Das Thema Node red ist eines, welches wir im 4. Quartal sehr gezielt angehen wollen. Aktuell haben wir von KUNBUS aus keinerlei Nodes für den IO Zugriff gebaut. ich weiß aber, dass sich einige aus der Community damit befasst haben. daher hoffe ich, dass dir hier vielleicht jemand schnell weiterhelfen kann.
Viel Erfolg,
Volker.
Das Thema Node red ist eines, welches wir im 4. Quartal sehr gezielt angehen wollen. Aktuell haben wir von KUNBUS aus keinerlei Nodes für den IO Zugriff gebaut. ich weiß aber, dass sich einige aus der Community damit befasst haben. daher hoffe ich, dass dir hier vielleicht jemand schnell weiterhelfen kann.
Viel Erfolg,
Volker.
Unser RevPi Motto: Don't just claim it - make it!
Moin Moin,
ich habe Euer RunningLight, etwas verändert und habe zumindest das Schaltverhalten gemäß meinen Anforderungen angepasst,
meine Frage wäre auf welcher Grundlage hier Programmiert wurde da hier offensichtlich mit Registern gearbeitet wurde.
Leider ist mir der Quellcode etwas zu kryptisch um alle details auslesen zu können.
Würde mich über eine Hilfestellung freuen, damit ich erstmal so meinen Versuchsaufbau abschließen kann bis eine passende
NodeRed-Palette verfügbar ist.
Hier noch einmal der angehängte Quellcode:
Viele Grüße
Joey
ich habe Euer RunningLight, etwas verändert und habe zumindest das Schaltverhalten gemäß meinen Anforderungen angepasst,
meine Frage wäre auf welcher Grundlage hier Programmiert wurde da hier offensichtlich mit Registern gearbeitet wurde.
Leider ist mir der Quellcode etwas zu kryptisch um alle details auslesen zu können.
Würde mich über eine Hilfestellung freuen, damit ich erstmal so meinen Versuchsaufbau abschließen kann bis eine passende
NodeRed-Palette verfügbar ist.
Hier noch einmal der angehängte Quellcode:
Code: Select all
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Description: This example implements a running light. It shows various ways to access data
# of the process image with python
# Hardware setup: DIO module RIGHT of the RevPi module. Outputs have to start at byte 81.
import time # used for the delays of the demo
import struct # used for the processing of byte-strings espectially with Python 2.7
import fcntl # used for the byte access of the process image within IOCTL
a=1 # Integer which is shifted within 14 positions in order to generate a running light at the DIO module
# first the driver has to be opened by the "open" statement:
f = open("/dev/piControl0","wb+",0)
# now the endless loop of the demo starts ...
while 1:
# Phase 1: Running light from PWM_1 to PWM_1 at the DIO <- also nur PWM-Signal auf 1 ausgeben
# This phase shows the access which is possible with Python 2.7 and Python 3.
# The struct library is used to generate a byte-string which is used by the
# write-function
for i in range(0,1): #Range verkürzt damit das Programm scchneller durchläuft und das schaltverhalten verkürzt wird
f.seek(81) # here the offset within the process image is set: Outputs start at byte 81 in the configuration
x = struct.pack('<H',(a<<i))
f.write(x) # here 2 bytes are written into the process image, because with 'H' the pack function packs 2 bytes into x
time.sleep(0.1)
# Phase 5: the 14 inputs are mirrored to the outputs
# we are reading the inputs now
f.seek(11) # Input start at offset 11 in this configuration
x = f.read(2) # 2 bytes are read
#i = x[0] + 256*x[1] # This simple convertion of Byte-string into integers is possible only with Python 3!
s = struct.unpack('<H',x) # this is the way which is possible with Python 2.7
i = s[0] # because is is a list we have to restrict the access to the first element
f.seek(81) # now we write the currently read data... Outputs start at offset 81 in this configuration
#f.write(i.to_bytes(2,'little')) # to_byte is just available in Python 3
f.write(struct.pack('<H',i)) # with Python 2.7 we need the struct-Library
time.sleep(0.1)
# first function: We are searching the offset and the byte of "Input_Pin_4" using KB_FIND_VARIABLE
prm = (b'K'[0]<<8) + 17 # the IOCTL-parameter is calculated using the ASCIIC 'K' which is shifted by 8 bits plus the ID of the desired function (=17)
name = struct.pack('37s',b"IN_1") # The arcument for the function 17 is a packed byte array with contains 37 bytes. The first 32 bytes consist of the symbolic name
ret = fcntl.ioctl(f,prm, name) # The result values are written into a byte-array
offset = struct.unpack_from('>H',ret,32)[0] # this is also possible in Python 2.7
bit = struct.unpack_from('B',ret,34)[0]
length = struct.unpack_from('H',ret,35)[0]
# now with the function 15 a single bit ("IN_1") is read out of the inputs...
prm = (b'K'[0]<<8) + 15
# The argument of the function is a bytearray with this stuct:
#typedef struct
#{
# uint16_t i16uAddress // Address of the byte in the process image
# uint8_t i8uBit // 0-7 bit position, >= 8 whole byte
# uint8_t i8uValue // Value: 0/1 for bit access, whole byte otherwise
#} SPIValue
value = bytearray([0,0,0,0])
struct.pack_into('>H',value,0,offset) # this is also possible in Python 2.7
struct.pack_into('B',value,2,bit)
fcntl.ioctl(f,prm,value)
bitval = value[3]
# once more the function 17. Now we want to know, where "PWM_1" is in the process image...
prm = (b'K'[0]<<8) + 17
name = struct.pack('37s',b"PWM_1")
ret = fcntl.ioctl(f,prm, name)
offset = struct.unpack_from('>H',ret,32)[0]
bit = struct.unpack_from('B',ret,34)[0]
length = struct.unpack_from('H',ret,35)[0]
# now with the function 16 a single bit ("PWM_1") is written to the outputs...
prm = (b'K'[0]<<8) + 16
value = bytearray([0,0,0,0])
struct.pack_into('>H',value,0,offset)
struct.pack_into('B',value,2,bit)
struct.pack_into('B',value,3,bitval)
fcntl.ioctl(f,prm,value)
time.sleep(3)
Joey
Hi,
lass mich bitte etwas konkrete wissen, was Dir unklar ist. Ich verstehe nämlich nicht, was Du unter "Regisertn" verstehst. Wir verwenden für den Zugriff auf das zentrale Prozessabbild Filebasierte Linuxzugriffe mit open, seek, read, write und close. Der rest in dem Demoprogramm ist eigentlich nur bit und byte jonglage, die durch Python als Programmiersprache im Vergleich zu C etwas kompliziert gerät. Zum Thema Prozessabbild solltest du ggf. erst mal den Blog vom Anfang her lesen. Dort ist erklärt, wie unsere IOs verarbeitet werden und was das prozessabbild ist und soll.
lass mich bitte etwas konkrete wissen, was Dir unklar ist. Ich verstehe nämlich nicht, was Du unter "Regisertn" verstehst. Wir verwenden für den Zugriff auf das zentrale Prozessabbild Filebasierte Linuxzugriffe mit open, seek, read, write und close. Der rest in dem Demoprogramm ist eigentlich nur bit und byte jonglage, die durch Python als Programmiersprache im Vergleich zu C etwas kompliziert gerät. Zum Thema Prozessabbild solltest du ggf. erst mal den Blog vom Anfang her lesen. Dort ist erklärt, wie unsere IOs verarbeitet werden und was das prozessabbild ist und soll.
Unser RevPi Motto: Don't just claim it - make it!
Hallo Volker,
durch die ganze High und Lowbyte Verschiebung bin ich davon ausgegangen, dass hier mit Registern gearbeitet wurde, (siehe ATMega16)
da ich das nur aus der Programmierung mit Assembler kenne.
Ich werde deinem Rat folgen und mir einmal die Prozessabläufe durchlesen.
Danke erstmal.
Lg Joey
durch die ganze High und Lowbyte Verschiebung bin ich davon ausgegangen, dass hier mit Registern gearbeitet wurde, (siehe ATMega16)
da ich das nur aus der Programmierung mit Assembler kenne.
Ich werde deinem Rat folgen und mir einmal die Prozessabläufe durchlesen.
Danke erstmal.
Lg Joey
Hi Joey,
die Byte-Jonglage ist halt die Schwäche von python, wo Du nicht wirklich Integer oder Word vom read-Aufruf bekommst, sondern einen python string. Der ist anders als ein c-string keine einfache Ansammlung von bytes (bytearray mit 0-byte an letzter Position) sondern ein eigenständiger Klassen-Typ, der konvertiert werden muss. Entweder machst Du das unter Python 2 mit der struct-Bibliothek (siehe Beispielprogramm) oder Du musst es mit der direkten Entnahme von Einzelbytes x[n] machen, die in Python 3 problemlos läuft. Aber wenn es um ein Word geht, dann musst Du bei dieser Art des Zugriffs auf dne Rückgabestring das lowbyte zum highbyte aufaddieren und das highbyte mit 256 multiplizieren.
Der Zugriff auf das prozessabbild geschieht immer über die Zugriffsfunktion vom PiControl-Treiber, die typisch für Linux mit einem file-basiertem IO passiert. Und der ist nun mal unter Python auf ein Stringobjekt zugeschnitten.
Das Prozessabbild (4k Speicherbereich) zu verwenden hat einen riesigen Vorteil: Alle Programme arbeiten dann mit einem zentralen Zugriff und müssen sich nicht weiter darum kümmern, dass die daten aus den IO-modulen irgendwie zyklisch in den revpi Core gelangen. Das erledigt piControl gesteuert durch die Konfiguration, die Du in PiCtory vornimmst und die in einer JSOn Datei hinterlegt wird, welche PiControl beim Starten einliest und als Basis für den Zugriff verwendet.
ich hoffe diese info hilft Dir halbwegs beim Verständnis, wie der Datenaustausch in der RevPi Gerätefamilie angedacht ist.
die Byte-Jonglage ist halt die Schwäche von python, wo Du nicht wirklich Integer oder Word vom read-Aufruf bekommst, sondern einen python string. Der ist anders als ein c-string keine einfache Ansammlung von bytes (bytearray mit 0-byte an letzter Position) sondern ein eigenständiger Klassen-Typ, der konvertiert werden muss. Entweder machst Du das unter Python 2 mit der struct-Bibliothek (siehe Beispielprogramm) oder Du musst es mit der direkten Entnahme von Einzelbytes x[n] machen, die in Python 3 problemlos läuft. Aber wenn es um ein Word geht, dann musst Du bei dieser Art des Zugriffs auf dne Rückgabestring das lowbyte zum highbyte aufaddieren und das highbyte mit 256 multiplizieren.
Der Zugriff auf das prozessabbild geschieht immer über die Zugriffsfunktion vom PiControl-Treiber, die typisch für Linux mit einem file-basiertem IO passiert. Und der ist nun mal unter Python auf ein Stringobjekt zugeschnitten.
Das Prozessabbild (4k Speicherbereich) zu verwenden hat einen riesigen Vorteil: Alle Programme arbeiten dann mit einem zentralen Zugriff und müssen sich nicht weiter darum kümmern, dass die daten aus den IO-modulen irgendwie zyklisch in den revpi Core gelangen. Das erledigt piControl gesteuert durch die Konfiguration, die Du in PiCtory vornimmst und die in einer JSOn Datei hinterlegt wird, welche PiControl beim Starten einliest und als Basis für den Zugriff verwendet.
ich hoffe diese info hilft Dir halbwegs beim Verständnis, wie der Datenaustausch in der RevPi Gerätefamilie angedacht ist.
Unser RevPi Motto: Don't just claim it - make it!
Hallo Volker,
auch ich bin an einen Punkt gekommen, wo ich wohl ohne Hardwarekontakt (DI) nicht mehr weiterkomme.
Bisher bin ich in meinem Projekt https://revolution.kunbus.de/forum/view ... f=13&t=393 mit Hilfe von Node RED schon ein gutes Stück weiter gekommen und der Feinstaubsensor liefert auch Daten. Nun soll der Sensor aber auch über Modbus in den Arbeitsmodus bzw. Schlafmodus gebracht werden. Leider wird der Modbus-Registerwert über ein einstellbares Zeitintervall laufend abgefragt.
Sendet man jedoch mehrfach den "Sleep-Befehl" für den Sensor, so hat dies zur Folge, dass der Sensor über den Sleep-Befehl in den Schlafmodus, und auch wieder in den Arbeitsmodus gebracht wird. Jede Anfrage über die serielle Schnittstelle des Sensors hat offensichtlich zur Folge, dass er aus dem Schlafmodus geweckt wird. Somit muss ich nun über einen Hardwarekontakt den Sensor in den Schlaf- oder Arbeitsmodus bringen. Für den Weg über Modbus will mir programmtechnisch keine Lösung einfallen.
Gibt es mittlerweile schon fertige Nodes für den IO Zugriff, oder siehst Du noch eine andere Möglichkeit?
Ein einziger DI würde mir schon reichen.
Gruß
Dieter
auch ich bin an einen Punkt gekommen, wo ich wohl ohne Hardwarekontakt (DI) nicht mehr weiterkomme.
Bisher bin ich in meinem Projekt https://revolution.kunbus.de/forum/view ... f=13&t=393 mit Hilfe von Node RED schon ein gutes Stück weiter gekommen und der Feinstaubsensor liefert auch Daten. Nun soll der Sensor aber auch über Modbus in den Arbeitsmodus bzw. Schlafmodus gebracht werden. Leider wird der Modbus-Registerwert über ein einstellbares Zeitintervall laufend abgefragt.
Sendet man jedoch mehrfach den "Sleep-Befehl" für den Sensor, so hat dies zur Folge, dass der Sensor über den Sleep-Befehl in den Schlafmodus, und auch wieder in den Arbeitsmodus gebracht wird. Jede Anfrage über die serielle Schnittstelle des Sensors hat offensichtlich zur Folge, dass er aus dem Schlafmodus geweckt wird. Somit muss ich nun über einen Hardwarekontakt den Sensor in den Schlaf- oder Arbeitsmodus bringen. Für den Weg über Modbus will mir programmtechnisch keine Lösung einfallen.
Gibt es mittlerweile schon fertige Nodes für den IO Zugriff, oder siehst Du noch eine andere Möglichkeit?
Ein einziger DI würde mir schon reichen.
Gruß
Dieter
Hallo Dieter,
wir kommen gerade vom ersten RevPi Day in Bremen, wo Boris von erminas der Community so etwas vorgeführt hat. Sich er kann er mal hier im Forum dazu etwas sagen und vielleicht sogar Code posten.
Und Dein Problem mit einmaligen Modbus Telegrammen (Eventverarbeitung) kenne ich all zu gut, weil ich bei einem RFID reader ein ähnliches Problem hatte.Leider gibt es da per SW aktuell keine wirkliche Lösung. Ich werde mal mit unserer Software Entwicklung sprechen, ob wir da nicht sehr zeitnah einen Weg finden, bestimmte Aufgaben in der Aufgabenliste des Masters nur per Abruf (z.B. nur einmal wenn sich der Wert im PA ändert oder so) auf den Modbus abzusetzen. Das wäre sicher eine gute Ergänzung für unseren Master.
wir kommen gerade vom ersten RevPi Day in Bremen, wo Boris von erminas der Community so etwas vorgeführt hat. Sich er kann er mal hier im Forum dazu etwas sagen und vielleicht sogar Code posten.
Und Dein Problem mit einmaligen Modbus Telegrammen (Eventverarbeitung) kenne ich all zu gut, weil ich bei einem RFID reader ein ähnliches Problem hatte.Leider gibt es da per SW aktuell keine wirkliche Lösung. Ich werde mal mit unserer Software Entwicklung sprechen, ob wir da nicht sehr zeitnah einen Weg finden, bestimmte Aufgaben in der Aufgabenliste des Masters nur per Abruf (z.B. nur einmal wenn sich der Wert im PA ändert oder so) auf den Modbus abzusetzen. Das wäre sicher eine gute Ergänzung für unseren Master.
Unser RevPi Motto: Don't just claim it - make it!
Hallo Volker,
Du hast den Nagel auf den Kopf getroffen. Schön, dass es dafür sogar einen Fachbegriff gibt. Eventbearbeitung, darauf muss man erstmal kommen.
Ich habe mich heute noch einmal mit einer Softwarelösung auseinander gesetzt und jetzt eine Idee entwickelt wie es evtl funktionieren könnte. Die ersten Versuche im Skripteditor sind positiv verlaufen. Ich befürchte nur, dass es in NodeRed nicht so laufen wird. Deshalb bin ich im Moment eher noch skeptisch, dass meine Softwarelösung funktionieren wird. Und wenn ich lese, dass ihr auch noch keine wirkliche SW-Lösung gefunden habt, dann werde ich im meiner Skepsis noch bestätigt. Über einen DI wäre es keine Problem die gewünschte Funktion zu bekommen, aber irgendwo ärgert es mich, dass es dafür (noch) keine SW-Lösung gibt.
Gruß Dieter
Du hast den Nagel auf den Kopf getroffen. Schön, dass es dafür sogar einen Fachbegriff gibt. Eventbearbeitung, darauf muss man erstmal kommen.
Ich habe mich heute noch einmal mit einer Softwarelösung auseinander gesetzt und jetzt eine Idee entwickelt wie es evtl funktionieren könnte. Die ersten Versuche im Skripteditor sind positiv verlaufen. Ich befürchte nur, dass es in NodeRed nicht so laufen wird. Deshalb bin ich im Moment eher noch skeptisch, dass meine Softwarelösung funktionieren wird. Und wenn ich lese, dass ihr auch noch keine wirkliche SW-Lösung gefunden habt, dann werde ich im meiner Skepsis noch bestätigt. Über einen DI wäre es keine Problem die gewünschte Funktion zu bekommen, aber irgendwo ärgert es mich, dass es dafür (noch) keine SW-Lösung gibt.
Gruß Dieter
Hallo Dieter.
da du ja mit Modbus und NodeJS arbeitetes sollte es doch kein Problem darstellen den Schlaf und wachmodus zu Programmieren,
Teile doch das ganze in 2 Befehle einen zum schlafen und einen zum erwachen.
hast du zwar im modbus eine Variable mehr aber das sollte gehen.
in node JS kannst du dann den Status abfragen und setzen was passieren soll
da du ja eh mit LC3 arbeitetest kannst du dort dein Programm anpassen und mit Modbus einfach abfragen.
Ich mache es auch nicht anders um einige Sachen zu realisieren wo mir die Physischen IOs fehlen.
gruß
da du ja mit Modbus und NodeJS arbeitetes sollte es doch kein Problem darstellen den Schlaf und wachmodus zu Programmieren,
Teile doch das ganze in 2 Befehle einen zum schlafen und einen zum erwachen.
hast du zwar im modbus eine Variable mehr aber das sollte gehen.
in node JS kannst du dann den Status abfragen und setzen was passieren soll
da du ja eh mit LC3 arbeitetest kannst du dort dein Programm anpassen und mit Modbus einfach abfragen.
Ich mache es auch nicht anders um einige Sachen zu realisieren wo mir die Physischen IOs fehlen.
gruß