Changes related to adding feed valve

This commit is contained in:
aniketSaha 2025-07-15 17:28:00 +02:00
parent e7b5cb1f8d
commit 21d24e1176
4 changed files with 418 additions and 11 deletions

View File

@ -5,7 +5,7 @@ import os
class CANBackend:
def __init__(self):
def __init__(self, eds_file =None):
self.network = None
self.nodes = {} # {1: RemoteNode(0x02), 2: RemoteNode(0x03), ...}
self.connected = False
@ -17,7 +17,10 @@ class CANBackend:
2: {}, # PU2
3: {} # PU3
}
self.eds_path = os.path.join(os.path.dirname(__file__), "eds_file", "processBoard_0.eds")
if eds_file is None:
self.eds_path = os.path.join(os.path.dirname(__file__), "eds_file", "processBoard_0.eds")
else:
self.eds_path = eds_file
def connect(self):
try:
@ -28,7 +31,8 @@ class CANBackend:
node_map = {
1: 0x02,
2: 0x04,
3: 0x127
3: 0x127,
4: 0xF
}
for pu_number, node_id in node_map.items():
@ -162,6 +166,18 @@ class CANBackend:
except Exception as e:
print(f"[SDO WRITE ERROR] PU{pu_number}: {e}")
raise
def send_command(self, opening :int):
try:
node = self.nodes.get(4)
if node is None:
raise ValueError(f"Feed valve is not connected")
node.sdo[0x6000].raw = opening
except Exception as e:
print(f"[SDO WRITE ERROR] Valve Board: {e}")
raise
def send_thermal_loop_cleaning(self, mode: str, pu_number: int):
if not self.connected:

View File

@ -0,0 +1,385 @@
; EDS file for inletvalveboard - generated by CANopen DeviceDesigner 3.14.2
[FileInfo]
FileName=inletvalveboard.eds
FileVersion=1.0
FileRevision=1.0
EDSVersion=4.0
Description=EDS
CreationTime=12:05PM
CreationDate=04-15-25
ModificationTime=12:05PM
ModificationDate=04-15-25
CreatedBy=Vineeta Gupta
ModifiedBy=Vineeta Gupta
[Comments]
Lines=1
Line1=generated by CANopen DeviceDesigner by emotas
[DeviceInfo]
VendorName=nehemis
VendorNumber=0x319
ProductName=InletValveController
ProductNumber=1234
RevisionNumber=0x1
OrderCode=InletValveController
BaudRate_10=0
BaudRate_20=0
BaudRate_50=0
BaudRate_125=0
BaudRate_250=1
BaudRate_500=0
BaudRate_800=0
BaudRate_1000=0
NrOfRxPDO=0
NrOfTxPDO=1
SimpleBootupSlave=1
SimpleBootupMaster=0
LSS_Supported=0
Granularity=0
DynamicChannelsSupported=0
GroupMessaging=0
[DummyUsage]
Dummy0001=0
Dummy0002=0
Dummy0003=0
Dummy0004=0
Dummy0005=0
Dummy0006=0
Dummy0007=0
[MandatoryObjects]
SupportedObjects=3
1=0x1000
2=0x1001
3=0x1018
[ManufacturerObjects]
SupportedObjects=2
1=0x2001
2=0x3000
[OptionalObjects]
SupportedObjects=13
1=0x1003
2=0x1008
3=0x1014
4=0x1015
5=0x1016
6=0x1017
7=0x1029
8=0x1200
9=0x1800
10=0x1a00
11=0x6000
12=0x6001
13=0x6002
[1000]
ParameterName=Device Type
ObjectType=7
DataType=7
AccessType=ro
PDOMapping=0
DefaultValue=0
[1001]
ParameterName=Error Register
ObjectType=7
DataType=5
AccessType=ro
PDOMapping=0
[1003]
ParameterName=Predefined Error Field
ObjectType=8
SubNumber=2
[1003sub0]
ParameterName=Number of Errors
ObjectType=7
DataType=5
AccessType=rw
PDOMapping=0
DefaultValue=0
[1003sub1]
ParameterName=Standard Error Field
ObjectType=7
DataType=7
AccessType=ro
PDOMapping=0
DefaultValue=0
[1008]
ParameterName=Manufacturer device name
ObjectType=7
DataType=9
AccessType=const
PDOMapping=0
DefaultValue=emotas Slave 1
[1014]
ParameterName=COB ID EMCY
ObjectType=7
DataType=7
AccessType=ro
PDOMapping=0
DefaultValue=$NODEID+0x80
[1015]
ParameterName=Inhibit Time Emergency
ObjectType=7
DataType=6
AccessType=rw
PDOMapping=0
DefaultValue=0x0
[1016]
ParameterName=Consumer Heartbeat Time
ObjectType=8
SubNumber=1
[1016sub0]
ParameterName=Number of entries
ObjectType=7
DataType=5
AccessType=ro
PDOMapping=0
DefaultValue=0
[1017]
ParameterName=Producer Heartbeat Time
ObjectType=7
DataType=6
AccessType=rw
PDOMapping=0
[1018]
ParameterName=Identity Object
ObjectType=9
SubNumber=5
[1018sub0]
ParameterName=Number of entries
ObjectType=7
DataType=5
AccessType=ro
PDOMapping=0
DefaultValue=4
[1018sub1]
ParameterName=Vendor Id
ObjectType=7
DataType=7
AccessType=ro
PDOMapping=0
DefaultValue=0x319
[1018sub2]
ParameterName=Product Code
ObjectType=7
DataType=7
AccessType=ro
PDOMapping=0
DefaultValue=1234
[1018sub3]
ParameterName=Revision number
ObjectType=7
DataType=7
AccessType=ro
PDOMapping=0
DefaultValue=0x1
[1018sub4]
ParameterName=Serial number
ObjectType=7
DataType=7
AccessType=ro
PDOMapping=0
[1029]
ParameterName=Error behaviour
ObjectType=8
SubNumber=3
[1029sub0]
ParameterName=Nr of Error Classes
ObjectType=7
DataType=5
AccessType=ro
PDOMapping=0
DefaultValue=2
[1029sub1]
ParameterName=Communication Error
ObjectType=7
DataType=5
AccessType=rw
PDOMapping=0
DefaultValue=1
[1029sub2]
ParameterName=Specific Error Class
ObjectType=7
DataType=5
AccessType=rw
PDOMapping=0
[1200]
ParameterName=Server SDO Parameter
ObjectType=9
SubNumber=3
[1200sub0]
ParameterName=Number of entries
ObjectType=7
DataType=5
AccessType=ro
PDOMapping=0
DefaultValue=2
[1200sub1]
ParameterName=COB ID Client to Server
ObjectType=7
DataType=7
AccessType=ro
PDOMapping=0
DefaultValue=$NODEID+0x600
[1200sub2]
ParameterName=COB ID Server to Client
ObjectType=7
DataType=7
AccessType=ro
PDOMapping=0
DefaultValue=$NODEID+0x580
[1800]
ParameterName=TPDO communication parameter
ObjectType=9
SubNumber=6
[1800sub0]
ParameterName=Highest sub-index supported
ObjectType=7
DataType=5
AccessType=const
PDOMapping=0
DefaultValue=6
[1800sub1]
ParameterName=COB-ID used by TPDO
ObjectType=7
DataType=7
AccessType=rw
PDOMapping=0
[1800sub2]
ParameterName=Transmission type
ObjectType=7
DataType=5
AccessType=rw
PDOMapping=0
[1800sub3]
ParameterName=Inhibit time
ObjectType=7
DataType=6
AccessType=rw
PDOMapping=0
[1800sub5]
ParameterName=Event timer
ObjectType=7
DataType=6
AccessType=rw
PDOMapping=0
[1800sub6]
ParameterName=SYNC start value
ObjectType=7
DataType=5
AccessType=rw
PDOMapping=0
[1a00]
ParameterName=Transmit PDO Mapping Parameter
ObjectType=9
SubNumber=2
;;This object contains the mapping for the PDO the device is able to transmit.
;;
[1a00sub0]
ParameterName=Highest sub-index supported
ObjectType=7
DataType=5
AccessType=const
PDOMapping=0
DefaultValue=1
[1a00sub1]
ParameterName=Mapping Entry 1
ObjectType=7
DataType=7
AccessType=const
PDOMapping=0
DefaultValue=0x60010008
[2001]
ParameterName=Manufacturer Object
ObjectType=7
DataType=4
AccessType=rw
PDOMapping=1
[3000]
ParameterName=Managed Array
ObjectType=8
SubNumber=3
[3000sub0]
ParameterName=NUmber of Entries
ObjectType=7
DataType=5
AccessType=ro
PDOMapping=0
DefaultValue=2
[3000sub1]
ParameterName=Sub 1
ObjectType=7
DataType=3
AccessType=ro
PDOMapping=1
[3000sub2]
ParameterName=sub 2
ObjectType=7
DataType=3
AccessType=rw
PDOMapping=1
[6000]
ParameterName=Position Set Point
ObjectType=7
DataType=5
AccessType=rw
PDOMapping=0
[6001]
ParameterName=Position Feedback
ObjectType=7
DataType=5
AccessType=rw
PDOMapping=1
[6002]
ParameterName=Motor Current
ObjectType=7
DataType=8
AccessType=rw
PDOMapping=1

20
main.py
View File

@ -29,6 +29,8 @@ router = APIRouter()
templates = Jinja2Templates(directory="templates")
logging.basicConfig(level=logging.INFO)
can_backend = CANBackend()
valve_backend = CANBackend(eds_file="/home/hmi/Desktop/HMI/eds_file/inletvalveboard.eds")
# Serve static files (HTML, JS, CSS)
app.mount("/static", StaticFiles(directory="static"), name="static")
@ -136,10 +138,15 @@ def connect_toggle():
return {"connected": False}
else:
success = can_backend.connect()
if not success:
raise HTTPException(status_code=500, detail="Connection failed.")
return {"connected": True}
try:
valve_backend.connect()
except Exception as e:
print(f"Connection error : {e}")
if not success:
raise HTTPException(status_code=500, detail="Connection failed.")
return {"connected": True}
@app.post("/command/{state}/pu/{pu_number}")
def send_command(state: str, pu_number: int, ploop_setpoint: float = Query(...)):
@ -191,7 +198,7 @@ async def update_latest_data():
data = can_backend.get_latest_data(pu_number=pu)
logging.info(f"[MONITOR BUFFER] PU{pu}: {data}")
latest_data[f"PU_{pu}"] = format_data(data)
await asyncio.sleep(0.1) # Update every 100ms
await asyncio.sleep(0.2) # Update every 100ms
@app.get("/monitor")
@ -215,13 +222,12 @@ def can_status():
@app.post("/command/feed_valve")
def can_status(MV01_opening: int = Query(...)):
def feedvalve_control(MV01_opening: int = Query(...)):
"""Control MV01 feed valve"""
# can_backend.send_command(MV01_opening) # TODO: TODO
valve_backend.send_command(MV01_opening) # TODO: TODO
logging.info(f"Feed valve opening to {MV01_opening}")
return {"status": "ok"}
app.include_router(router)
if __name__ == "__main__":

View File

@ -194,7 +194,7 @@
yaxis: { title: 'Pressure (bar)', range: [0, 15] }
});
setInterval(updatePlots, 250);
setInterval(updatePlots, 500);
}
window.onload = initPlots;