diff --git a/Makefile b/Makefile index a7bad8b..adb3a5b 100644 --- a/Makefile +++ b/Makefile @@ -20,3 +20,4 @@ TEMPLATES += templates/shutter.substitutions # Scripts to include in the release SCRIPTS += scripts/shutter.cmd +SCRIPTS += sim/shutter_sim.py diff --git a/db/readbit.db b/db/readbit.db index 8b96ac0..623c796 100644 --- a/db/readbit.db +++ b/db/readbit.db @@ -1,4 +1,4 @@ -record(bi,"$(PREFIX)$(SPS_REGISTER_NAME):$(BIT_NAME)") +record(bi,"$(PREFIX):$(SPS_REGISTER_NAME):$(BIT_NAME)") { field(DTYP, "S7plcFW") field(INP, "@$(SPS_REGISTER_NAME)/$(OFFSET) T=BYTE B=$(BIT)") diff --git a/db/readstring.db b/db/readstring.db index df33ef0..a700a3d 100644 --- a/db/readstring.db +++ b/db/readstring.db @@ -1,4 +1,4 @@ -record(stringin, "$(PREFIX)$(SPS_REGISTER_NAME):$(STRING_NAME)-Msg") +record(stringin, "$(PREFIX):$(SPS_REGISTER_NAME):$(STRING_NAME)-Msg") { field(DTYP, "S7plcFW") field(INP, "@$(SPS_REGISTER_NAME)/$(OFFSET) L=$(LENGTH)") diff --git a/db/sps_status.db b/db/sps_status.db index 37f6540..708a3f1 100644 --- a/db/sps_status.db +++ b/db/sps_status.db @@ -1,4 +1,4 @@ -record(bi, "$(PREFIX)$(SPS_REGISTER_NAME):ConnStatusFetch") +record(bi, "$(PREFIX):$(SPS_REGISTER_NAME):ConnStatusFetch") { field(DTYP, "S7plcFW stat") field(INP, "@$(SPS_REGISTER_NAME)") @@ -7,7 +7,7 @@ record(bi, "$(PREFIX)$(SPS_REGISTER_NAME):ConnStatusFetch") field(SCAN, "I/O Intr") } -record(bi, "$(PREFIX)$(SPS_REGISTER_NAME):ConnStatusWrite") +record(bi, "$(PREFIX):$(SPS_REGISTER_NAME):ConnStatusWrite") { field(DTYP, "S7plcFW stat2") field(INP, "@$(SPS_REGISTER_NAME)") diff --git a/db/writebit.db b/db/writebit.db index 48a6a7e..e55cda8 100644 --- a/db/writebit.db +++ b/db/writebit.db @@ -1,4 +1,4 @@ -record(bo, "$(PREFIX)$(SPS_REGISTER_NAME):$(BIT_NAME)") +record(bo, "$(PREFIX):$(SPS_REGISTER_NAME):$(BIT_NAME)") { field(DTYP, "S7plcFW") field(OUT, "@$(SPS_REGISTER_NAME)/$(OFFSET) T=BYTE B=$(BIT)") diff --git a/scripts/shutter.cmd b/scripts/shutter.cmd index ff3ba52..7b8477e 100644 --- a/scripts/shutter.cmd +++ b/scripts/shutter.cmd @@ -11,14 +11,24 @@ require s7plcFW # # out IO Interrupt Delay (if 0 then only reacts on a change) # ) -epicsEnvSet("SPS_REGISTER_NAME", "$(SPS_REGISTER_NAME=SPS-$(FETCH_DB))") +epicsEnvSet("SPS_REGISTER_NAME", "SPS-$(FETCH_DB)") epicsEnvSet("SPS_FETCH_SIZE", "152") -epicsEnvSet("SPS_WRITE_SIZE", "1") +# Seems that 1 doesn't work +epicsEnvSet("SPS_WRITE_SIZE", "2") -s7plcFWConfigure("$(SPS_REGISTER_NAME)", "$(SPS_IP)", "$(FETCH_PORT=2000),1,$(FETCH_DB),2,$(SPS_FETCH_SIZE)", "$(WRITE_PORT=2001),1,$(WRITE_DB=$(FETCH_DB)),2,$(SPS_WRITE_SIZE)", $(SPS_ENDIANNESS=1), $(SPS_RECEIVE_TIMEOUT=1000), $(SPS_RECEIVE_DELAY=200), 0) + +$(SET_SIM_MODE=#) $(SET_SIM_MODE) require misc +$(SET_SIM_MODE=#) $(SET_SIM_MODE) epicsEnvSet("SPS_IP", "127.0.0.1") +$(SET_SIM_MODE=#) $(SET_SIM_MODE) system "$(sinqSPS_DIR)shutter_sim.py $(FETCH_PORT=2000) $(WRITE_PORT=2001) &" +# starting the python socket seems to take a while +# and need misc to use built in sleep command +$(SET_SIM_MODE=#) $(SET_SIM_MODE) sleep 3 + + +s7plcFWConfigure("$(SPS_REGISTER_NAME)", "$(SPS_IP)", "$(FETCH_PORT=2000),1,$(FETCH_DB),0,$(SPS_FETCH_SIZE)", "$(WRITE_PORT=2001),1,$(WRITE_DB=$(FETCH_DB)),0,$(SPS_WRITE_SIZE)", "$(SPS_ENDIANNESS=1)", "$(SPS_RECEIVE_TIMEOUT=1000)", "$(SPS_RECEIVE_DELAY=200)", "0") # Provides Connection Status PVs -dbLoadRecords("$(sinqSPS_DB)/sps_status.db") +# dbLoadRecords("$(sinqSPS_DB)/sps_status.db", "PREFIX=$(PREFIX), SPS_REGISTER_NAME=$(SPS_REGISTER_NAME)") # Shutter PVs -dbLoadTemplate("$(sinqSPS_DB)/shutter.substitions") +dbLoadTemplate("$(sinqSPS_DB)/shutter.substitutions", "PREFIX=$(PREFIX), SPS_REGISTER_NAME=$(SPS_REGISTER_NAME)") diff --git a/sim/.__afs7E221F9A5 b/sim/.__afs7E221F9A5 new file mode 100755 index 0000000..afe6af4 --- /dev/null +++ b/sim/.__afs7E221F9A5 @@ -0,0 +1,13 @@ +#!/usr/local/bin/iocsh + +on error break + +require sinqSPS, wall_e + +epicsEnvSet("STREAM_PROTOCOL_PATH","./db") +epicsEnvSet("PREFIX","SQ:TEST") + +epicsEnvSet("SET_SIM_MODE","") # Run Shutter Simulation Instead of Connecting with SPS +runScript "$(sinqSPS_DIR)shutter.cmd" "SPS_IP=127.0.0.1, FETCH_DB=210, FETCH_PORT=2002, WRITE_PORT=2003" + +iocInit() diff --git a/sim/ioc.sh b/sim/ioc.sh new file mode 100755 index 0000000..ef9bd7f --- /dev/null +++ b/sim/ioc.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +export EPICS_HOST_ARCH=linux-x86_64 +export EPICS_BASE=/usr/local/epics/base-7.0.7 + +PARENT_PATH="$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )" + +echo "${PARENT_PATH}/st.cmd" +/usr/local/bin/procServ -L - -f -i ^D^C 20001 "${PARENT_PATH}/st.cmd" diff --git a/sim/shutter_sim.py b/sim/shutter_sim.py new file mode 100644 index 0000000..4f52786 --- /dev/null +++ b/sim/shutter_sim.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 + +import logging +import os +import re +import socket +import sys +import time + +from threading import Thread + +HOST = "127.0.0.1" # Localhost +READ_PORT = int(sys.argv[1]) # Port to listen on +WRITE_PORT = int(sys.argv[2]) # Port to listen on + +LOG2FILE = True # TODO False if len(sys.argv) < 3 else bool(int(sys.argv[3])) + +logger = logging.getLogger('shutter') + +if LOG2FILE: + logging.basicConfig(filename=os.path.join(os.getcwd(), 'shutter_sim.log'), level=logging.INFO) + +logger.info(f'Read Requests on {HOST}:{READ_PORT}, Write Requests on {HOST}:{WRITE_PORT}') + +def receive(conn, sock_name): + # received = conn.recv(1024, socket.MSG_DONTWAIT) + received = conn.recv(1024) + logger.info(f'RECEIVED on {sock_name}: "{received}"') + logger.info('Decimal on %s: %s' % (sock_name, ' '.join(map(str, [received[i+2] for i in range(len(received)-2)])))) + return received + +def send(conn, data: str): + logger.info(f'SENDING: "{data}"') + return conn.sendall(data) + +def read_requests(): + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + + s.bind((HOST, READ_PORT)) + s.listen() + conn, _ = s.accept() + + with conn: + while True: + data = receive(conn, "read") + + # if not data: # Empty implies client disconnected + # break # Close Server + + try: + + if data == b'': + send(conn, b'') + + elif len(data) == 14 and data[0] == 83 and data[1] == 53: + # Trying to fetch data + org = data[8] + db = data[9] + s7addr = data[10] * 256 + data[11] + s7len = data[12] * 256 + data[13] + logger.info(f'Fetch: db: {db}, address: {s7addr}, total: {s7len}') + + send(conn, b'0' * s7len) + + except Exception as e: + logger.exception('Simulation Broke') + # send('?OV') + +def write_requests(): + + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + + s.bind((HOST, WRITE_PORT)) + s.listen() + conn, _ = s.accept() + + with conn: + while True: + data = receive(conn, "write") + + # if not data: # Empty implies client disconnected + # break # Close Server + + +read_thread = Thread(target=read_requests) +write_thread = Thread(target=write_requests) + +read_thread.run() +write_thread.run() + +while True: + pass diff --git a/sim/st.cmd b/sim/st.cmd new file mode 100755 index 0000000..6a1dcb5 --- /dev/null +++ b/sim/st.cmd @@ -0,0 +1,13 @@ +#!/usr/local/bin/iocsh + +on error break + +require sinqSPS, wall_e + +epicsEnvSet("STREAM_PROTOCOL_PATH","./db") +epicsEnvSet("PREFIX","SQ:TEST") + +epicsEnvSet("SET_SIM_MODE","") # Run Shutter Simulation Instead of Connecting with SPS +runScript "$(sinqSPS_DIR)shutter.cmd" "SPS_IP=127.0.0.1, FETCH_DB=210, FETCH_PORT=2030, WRITE_PORT=2031" + +iocInit()