diff --git a/CHANGELOG.md b/CHANGELOG.md
index 21ea4e06613a392f826a320ce4b145703bdceb74..783f537ab31554eec26a6ef8cd4949d491d4b5c3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
 # Changelog
 
+## demi-7 tag
+*optoboard_felix-1.0.47*
+- Compatible with FELIX FW 5.0 and SW 05-00-04
+- optoboard.log ownership issue fixed
+- New endpoint for eye monitoring diagram with DC offset (or bias) calculation
+- Reorganisation of soft error endpoints - now two endpoints for counter and scan that can be used on either single or multiple links
+    - In the case of scans, the links must come from the same device
+
 ## demi-6 tag
 *optoboard-felix-1.0.43*
 - Configdb included in itk-demo-optoboard. Possibility to use it or not.
diff --git a/api/Dockerfile b/api/Dockerfile
index a591240294989d99a8f8ca26b203102fe7399964..2e4c3c376cad0ec0c7fc49cbf17bcc41f705497a 100644
--- a/api/Dockerfile
+++ b/api/Dockerfile
@@ -1,13 +1,9 @@
-# FROM gitlab-registry.cern.ch/atlas-itk-pixel-systemtest/itk-demo-sw/containers/optoboard-container/optoboard-container:latest
 ARG OPTO_BASE_IMAGE
 FROM ${OPTO_BASE_IMAGE}
 
 ENV HOME="/root"
 WORKDIR ${HOME}
 
-# -- install from source: no longer needed
-# RUN git clone https://gitlab.cern.ch/atlas-itk-pixel-systemtest/itk-demo-sw/${PROJECT}.git
-
 # -- pip install needs to be fixed.
 # RUN pip install git+https://gitlab.cern.ch/atlas-itk-pixel-systemtest/itk-demo-sw/itk-demo-optoboard.git
 
@@ -16,15 +12,9 @@ SHELL ["/bin/bash", "--login", "-c"]
 COPY . .
 
 ### Installation with poetry
-RUN python3 -m pip install -U pip
-RUN python3 -m pip install 'python-dotenv<2.0.0' 'Flask-Cors<3.1.0' 'celery[redis]<6.0.0' 'connexion[swagger-ui]<3.0.0' 'gunicorn<21.0.0' 'PyAMQP<1.0.0' git+https://gitlab.cern.ch/atlas-itk-pixel-systemtest/itk-demo-sw/pypi-packages/rcf-response.git
-RUN pip install pyconfigdb --index-url https://gitlab.cern.ch/api/v4/projects/180899/packages/pypi/simple
-
-# RUN python3 -m pip install --no-cache-dir poetry==1.5.1 && \
-#     poetry config virtualenvs.create false && \
-#     poetry install
-# RUN poetry export --format=requirements.txt --output=requirements.txt --without-hashes
-# RUN python3 -m pip install -r requirements.txt
+RUN python3 -m pip install -U pip && \
+    python3 -m pip install 'python-dotenv<2.0.0' 'Flask-Cors<3.1.0' 'celery[redis]<6.0.0' 'connexion[swagger-ui]<3.0.0' 'gunicorn<21.0.0' 'PyAMQP<1.0.0' git+https://gitlab.cern.ch/atlas-itk-pixel-systemtest/itk-demo-sw/pypi-packages/rcf-response.git && \
+    mkdir /results
 
 COPY root /
 
diff --git a/api/itk_demo_optoboard/api/openapi/openapi.yaml b/api/itk_demo_optoboard/api/openapi/openapi.yaml
index c1f2df0b18b71e26f2c739bf5a6c58127d9b7e06..a16d24100824c954c688d09ceae758063ce5e511 100644
--- a/api/itk_demo_optoboard/api/openapi/openapi.yaml
+++ b/api/itk_demo_optoboard/api/openapi/openapi.yaml
@@ -328,12 +328,12 @@ paths:
 
   /softErrorScan:
     post:
-      summary: Performs a soft error scan
-      description: Perform a 2D soft error scan as a function of the parameters of the equalizer of the GBCR.
+      summary: Performs a soft error scan on one link or multiple links of the same device
+      description: Perform a 2D soft error scan as a function of the parameters of the equalizer of the GBCR, for one link or for multiple links on the same device
       x-openapi-router-controller: itk_demo_optoboard.api.routes
       operationId: softErrorScan
       requestBody:
-        description: JSON serialized object containing the parameters of the bert script
+        description: JSON serialized object containing soft error scan parameters
         content:
           application/json:
             schema:
@@ -343,18 +343,13 @@ paths:
                   type: string
                   example: "OB0"
                   description: Optoboard position
-                optical_link:
-                  type: string
-                  example: "00"
-                  description: optical link to monitor
-                felix_device:
-                  type: string
-                  example: "0"
-                  description: Felix device in use
-                egroup:
-                  type: string
-                  example: "00"
-                  description: egroup to monitor
+                dev_olink_egrp:
+                  description: A combination of FELIX device, optical link and egroup
+                  type: array
+                  items:
+                    type: string
+                  minItems: 1
+                  example: ["0_00_1"]
                 gbcr_name:
                   type: string
                   example: "gbcr1"
@@ -392,9 +387,7 @@ paths:
                   example: "1"
                   description: level of detail of the scan of the GBCR parameters (default 1)
               required:
-                - optical_link
-                - felix_device 
-                - egroup
+                - dev_olink_egrp
                 - gbcr_name
                 - meastime
                 - filename
@@ -446,59 +439,6 @@ paths:
         200:
           $ref: "#/components/schemas/standard_model"
 
-  /softErrorCounter:
-    post:
-      summary: Performs a soft error counnt
-      description: The number of soft errors is monitored by checking the associated felix register.
-      x-openapi-router-controller: itk_demo_optoboard.api.routes
-      operationId: softErrorCounter
-      requestBody:
-        description: JSON serialized object containing the parameters of the bert script
-        content:
-          application/json:
-            schema:
-              type: object
-              properties:
-                optoboardPosition:
-                  type: string
-                  example: "OB0"
-                  description: Optoboard position
-                optical_link:
-                  type: string
-                  example: "00"
-                  description: optical link to monitor, example "00" for felix channel 0
-                felix_device:
-                  type: string
-                  example: "0"
-                  description: Felix device in use
-                egroup:
-                  type: string
-                  example: "00"
-                  description: lpGBT egroup to monitor
-                meastime:
-                  type: string
-                  example: "12"
-                  description: measuring time in seconds
-                API:
-                  type: string
-                  example: "1"
-                  description: use endpoint call to monitor the soft error (0 or 1)
-                url:
-                  type: string
-                  example: "http://felix:8000"
-                  description: url of the server with FELIX backend, url of the server with FELIX backend if the SR is not successful
-              required:
-                - optical_link
-                - felix_device
-                - egroup
-                - meastime
-                - API
-                - url
-      responses:
-        200:
-          $ref: "#/components/responses/SOFTERRORCounter_response" 
-
-
   /swapPolarity:
     post:
       summary: Swaps polarities of uplinks (tx)/downlinks (rx)
@@ -610,12 +550,12 @@ paths:
               schema:
                 type: object    
 
-  /parallelsoftErrorCounter:
+  /softErrorCounter:
     post:
-      summary: Runs a parallel soft error scan
-      description: Runs a parallel soft error scan, possible on multiple egroups and optical links on multiple devices
+      summary: Runs a soft error scan, which can either be for one egroup or parallelised
+      description: Runs a soft error scan, possible on multiple egroups and optical links on multiple devices, or just a single egroup
       x-openapi-router-controller: itk_demo_optoboard.api.routes
-      operationId: parallelsoftErrorCounter
+      operationId: softErrorCounter
       requestBody:
         description: JSON serialised object containing device, a combined variable for FELIX device, optical link and egroup, and measurement time 
         content:
@@ -637,10 +577,13 @@ paths:
                 meastime:
                   type: string
                   example: "10"
-                  description: Length of the soft error test              
+                  description: Length of the soft error test  
+              required:
+                - dev_olink_egrp
+                - meastime
       responses:
         200:
-          description: JSON serialized object containing the status of the optoboard microservice
+          description: JSON serialized object containing the filename, DC offset
           content:
             application/json:
               schema:
@@ -668,14 +611,53 @@ paths:
                 device:
                   type: string
                   example: "lpgbt1"
-                  description: device
+                  description: Device
                 monitor_channel:
                   type: string
                   example: "0"
+                  description: Channel for which voltage should be monitored
       responses:
         200:
           description: Voltage value
 
+  /eyeMonitorDiagram:
+    post:
+      summary: Eye monitor diagram with DC offset monitoring
+      description: Produces an eye monitor diagram and an array of the XY values of the plot of the 2.56 Gbps downlink. Only possible with lpGBT1.
+      x-openapi-router-controller: itk_demo_optoboard.api.routes
+      operationId: eyeMonitorDiagram
+      requestBody:
+        description: JSON serialised object containing device, meastime, and filename
+        content:
+          application/json:
+            schema:
+              type: object
+              properties:
+                optoboardPosition:
+                  type: string
+                  example: "OB0"
+                  description: Optoboard position
+                device:
+                  type: string
+                  example: "lpgbt1"
+                  description: Device
+                meastime:
+                  type: string
+                  example: "10"
+                  description: Measurement time
+                filename:
+                  type: string
+                  example: "Eye_monitor_diagram"
+                  description: Filename for diagram plot
+      responses:
+        200:
+          description: XY values of diagram and DC offset
+          content:
+            application/json:
+              schema:
+                type: object
+
+
   /setLpgbtPhase:
     post:
       summary: Change phase mode of lpGBT
@@ -696,7 +678,7 @@ paths:
                 device:
                   type: string
                   example: "lpgbt1"
-                  description: device
+                  description: Device
                 phaseMode:
                   type: string
                   example: "fixed_phase"
@@ -704,7 +686,7 @@ paths:
                 group:
                   type: string
                   example: "4"
-                  description: e-group number
+                  description: E-group number
                 phase:
                   type: string
                   example: "5"
diff --git a/api/itk_demo_optoboard/api/routes.py b/api/itk_demo_optoboard/api/routes.py
index c5002cb10976f933f56b8dc6d5130d73cd022ae9..e73cf1c72e3c00ac4ed932d8794414867342eaac 100644
--- a/api/itk_demo_optoboard/api/routes.py
+++ b/api/itk_demo_optoboard/api/routes.py
@@ -60,7 +60,6 @@ def modifyOptoGUIConf():
 
 def writeRegister():
     payload = request.get_json()
-
     optoboardPosition = str(payload["optoboardPosition"])
     device = str(payload["device"])
     register = str(payload["register"])
@@ -208,14 +207,14 @@ def phaseScan():
     bertmeastime = int(payload["bertmeastime"])
     queue = "itk_demo_optoboard_queue_" + optoboardPosition
     return _error_catcher(
-        PHASESCAN_Task.apply_async(
+        phaseScanTask.apply_async(
             (optoboardPosition, device,eprx_group, bertmeastime),
             queue=queue,
         ).wait
     )
         
 
-def softErrorCounter():
+'''def softErrorCounter():
     payload = request.get_json()
     optoboardPosition = str(payload["optoboardPosition"])
     optical_link = str(payload["optical_link"])
@@ -226,19 +225,28 @@ def softErrorCounter():
     url = str(payload["url"])
     queue = "itk_demo_optoboard_queue_" + optoboardPosition
     return _error_catcher(
-        SOFTERRORCOUNTER_Task.apply_async(
+        softErrorCounterTask.apply_async(
             (optoboardPosition, optical_link, felix_device, egroup, meastime, API, url),
             queue=queue,
         ).wait
-    )
+    )'''
+    
         
+def softErrorCounter():
+    payload = request.get_json()
+    optoboardPosition = str(payload["optoboardPosition"])
+    dev_olink_egrp = list(payload["dev_olink_egrp"])
+    meastime = int(payload["meastime"])
+    queue = "itk_demo_optoboard_queue_" + optoboardPosition
+    return _error_catcher(
+        softErrorCounterTask.apply_async((optoboardPosition,dev_olink_egrp,meastime),queue=queue).wait
+    )
+
 
 def softErrorScan():
     payload = request.get_json()
     optoboardPosition = str(payload["optoboardPosition"])
-    optical_link = str(payload["optical_link"])
-    felix_device = int(payload["felix_device"])
-    egroup = int(payload["egroup"])
+    dev_olink_egrp = list(payload["dev_olink_egrp"])
     gbcr_name = str(payload["gbcr_name"])
     meastime = int(payload["meastime"])
     filename = str(payload["filename"])
@@ -250,8 +258,8 @@ def softErrorScan():
     jump = int(payload["jump"])
     queue = "itk_demo_optoboard_queue_" + optoboardPosition
     return _error_catcher(
-        SOFTERRORSCAN_Task.apply_async(
-            (optoboardPosition, optical_link, felix_device, egroup, gbcr_name, meastime, filename, plot, HFmin, HFmax, MFmin, MFmax, jump),
+        softErrorScanTask.apply_async(
+            (optoboardPosition, dev_olink_egrp, gbcr_name, meastime, filename, plot, HFmin, HFmax, MFmin, MFmax, jump),
             queue=queue,
         ).wait
     )
@@ -266,7 +274,7 @@ def BERT():
     meastime = int(payload["meastime"])
     queue = "itk_demo_optoboard_queue_" + optoboardPosition
     return _error_catcher(
-        BERT_Task.apply_async(
+        bertTask.apply_async(
             (optoboardPosition, device, channel, meastime),
             queue=queue,
         ).wait
@@ -346,25 +354,26 @@ def readLog():
         readLogTask.apply_async(queue="itk_demo_optoboard_queue").wait
     )
     
-def parallelsoftErrorCounter():
+def readLpgbtSupplyVoltage():
     payload = request.get_json()
     optoboardPosition = str(payload["optoboardPosition"])
-    dev_olink_egrp = list(payload["dev_olink_egrp"])
-    meastime = int(payload["meastime"])
+    device = str(payload["device"])
+    monitor_channel = int(payload["monitor_channel"])
     queue = "itk_demo_optoboard_queue_" + optoboardPosition
     return _error_catcher(
-        parallelsoftErrorCounterTask.apply_async((optoboardPosition,dev_olink_egrp,meastime),queue=queue).wait
+        readSupplyVoltageTask.apply_async((optoboardPosition,device,monitor_channel),queue=queue).wait
     )
     
-def readLpgbtSupplyVoltage():
+def eyeMonitorDiagram():
     payload = request.get_json()
     optoboardPosition = str(payload["optoboardPosition"])
     device = str(payload["device"])
-    monitor_channel = int(payload["monitor_channel"])
+    meastime = int(payload["meastime"])
+    filename = str(payload["filename"])
     queue = "itk_demo_optoboard_queue_" + optoboardPosition
     return _error_catcher(
-        readSupplyVoltageTask.apply_async((optoboardPosition,device,monitor_channel),queue=queue).wait
-    )
+        eyeMonitorDiagramTask.apply_async((optoboardPosition,device,meastime,filename),queue=queue).wait
+    )   
 
 # from itk_demo_optoboard.wsgi import celery
 from itk_demo_optoboard.worker.celeryTasks import *
diff --git a/api/itk_demo_optoboard/worker/celeryTasks.py b/api/itk_demo_optoboard/worker/celeryTasks.py
index ee15992166612efd9f7d341b05220968f20751a8..a4dd5e967bc1d7ab61926eb2eaac9e49ba4303d6 100644
--- a/api/itk_demo_optoboard/worker/celeryTasks.py
+++ b/api/itk_demo_optoboard/worker/celeryTasks.py
@@ -255,32 +255,31 @@ def configureAllTask():
             return "Configuration failed"
     return "Configuration completed"
 
-### task for PHASE SCAN
 
 @celery.task()
-def PHASESCAN_Task(optoboardPosition, device,eprx_group, bertmeastime):
-    PHASESCAN_result = eval('optoboard_dic["' + optoboardPosition + '"].' + device).bert_by_phase(eprx_group, bertmeastime, 6)
-    return PHASESCAN_result
+def phaseScanTask(optoboardPosition, device,eprx_group, bertmeastime):
+    phaseScan_result = eval('optoboard_dic["' + optoboardPosition + '"].' + device).bert_by_phase(eprx_group, bertmeastime, 6)
+    return phaseScan_result
 
-### task for SOFT ERROR COUNTER
 
-@celery.task()
-def SOFTERRORCOUNTER_Task(optoboardPosition, optical_link, felix_device, egroup, meastime, API=True, url="http://felix:8000"):
-    SOFTERRORCOUNTER_result = optoboard_dic[optoboardPosition].softErrorCounter(optical_link, felix_device, egroup, meastime, API, url)
-    return SOFTERRORCOUNTER_result
+'''@celery.task()
+def softErrorCounterTask(optoboardPosition, optical_link, felix_device, egroup, meastime, API=True, url="http://felix:8000"):
+    softErrorCounter_result = optoboard_dic[optoboardPosition].softErrorCounter(optical_link, felix_device, egroup, meastime, API, url)
+    return softErrorCounter_result'''
 
-### task for SOFT ERROR SCAN
 
 @celery.task()
-def SOFTERRORSCAN_Task(optoboardPosition, optical_link, felix_device, egroup, gbcr_name, meastime, filename="softErrorScan_result", plot=False, HFmin=0, HFmax=15, MFmin=0, MFmax=15, jump=1):
-    SOFTERRORSCAN_result = optoboard_dic[optoboardPosition].softErrorScan(optical_link, felix_device, egroup, gbcr_name, meastime, filename, plot, HFmin, HFmax, MFmin, MFmax, jump)
-    return SOFTERRORSCAN_result
-
-
-### task for BER test
+def softErrorScanTask(optoboardPosition, dev_olink_egrp, gbcr_name, meastime, filename="softErrorScan_result", plot=False, HFmin=0, HFmax=15, MFmin=0, MFmax=15, jump=1):
+    try:
+        softErrorScan_result = optoboard_dic[optoboardPosition].softErrorScan(dev_olink_egrp, gbcr_name, meastime, filename, plot, HFmin, HFmax, MFmin, MFmax, jump)
+        return softErrorScan_result
+    except Exception as e:
+        logger.error("Task terminated due to exception: " + str(e))
+        return "Could not perform soft error scan!"
+    return "Soft error scan files created!"
 
 @celery.task()
-def BERT_Task(optoboardPosition, device, channel, meastime):
+def bertTask(optoboardPosition, device, channel, meastime):
     BERT_result = eval('optoboard_dic["' + optoboardPosition + '"].' + device).bert(channel, meastime, 6)
     return BERT_result
 
@@ -327,16 +326,16 @@ def configureI2CControllerTask(optoboardPosition, device):
 @celery.task()
 def dumpCustomRegConfigTask(optoboardPosition,filename):
     try:
-        optoboard_dic[optoboardPosition].dump_opto_config(str(filename))
+        optoboard_dic[optoboardPosition].dump_opto_config(filename)
     except Exception as e:
             logger.error("Task terminated due to exception: " + str(e))
             return "Could not create configuration file!"
     return "Finished!"
 
 @celery.task()
-def parallelsoftErrorCounterTask(optoboardPosition,dev_olink_egrp,meastime):
+def softErrorCounterTask(optoboardPosition,dev_olink_egrp,meastime):
     try:
-        softerrors = optoboard_dic[optoboardPosition].parallelsoftErrorCounter(dev_olink_egrp,meastime)
+        softerrors = optoboard_dic[optoboardPosition].softErrorCounter(dev_olink_egrp,meastime)
         return softerrors
     except Exception as e:
         logger.error("Task terminated due to exception: " + str(e))
@@ -350,3 +349,12 @@ def readSupplyVoltageTask(optoboardPosition, device, monitor_channel):
     except Exception as e:
         logger.error("Task terminated due to exception: " + str(e))
         return "Could not read supply voltage of " + device + "!"
+    
+@celery.task()
+def eyeMonitorDiagramTask(optoboardPosition, device, meastime, filename):
+    try:
+        emd = eval('optoboard_dic["' + optoboardPosition + '"].' + device).eye_opening_monitor(meastime,filename)
+        return emd
+    except Exception as e:
+        logger.error("Task terminated due to exception: " + str(e))
+        return "Could not produce eye monitior diagram for " + device + "!"
diff --git a/api/root/etc/s6-overlay/s6-rc.d/run-service/run b/api/root/etc/s6-overlay/s6-rc.d/run-service/run
index f6edf404ee49999a9f8937d080dc026b149da1da..551cea4042d0a61cb04d0fccfe2a34ca5ec8467a 100755
--- a/api/root/etc/s6-overlay/s6-rc.d/run-service/run
+++ b/api/root/etc/s6-overlay/s6-rc.d/run-service/run
@@ -1,5 +1,37 @@
 #!/command/with-contenv bash
 
+# Noisy chown alias to handle read-only/remote volumes
+cat <<-EOF >/usr/bin/demiown
+#!/bin/bash
+chown "\$@" || printf '**** Permissions to $2 could not be set. This is probably because your volume mounts are remote or read-only. ****\n**** The app may not work properly. ****\n'
+EOF
+chmod +x /usr/bin/demiown
+
+cat <<-EOF >/usr/bin/demimod
+#!/bin/bash
+chmod "\$@" || printf '**** Permissions to $2 could not be set. This is probably because your volume mounts are remote or read-only. ****\n**** The app may not work properly. ****\n'
+EOF
+chmod +x /usr/bin/demimod
+
+demiown itk:itk /config
+demiown itk:itk /results
+demiown -R itk:itk /root
+
+ITK_UID=$(id -u itk)
+
+# Check if the UID is different from 1111
+if [ "$ITK_UID" -ne 1111 ]; then
+    echo "Taking posession of /workspace with 'itk' UID $ITK_UID."
+    demiown -R itk:itk /workspace
+else
+    echo "The user 'itk' has UID 1111, meaning it is probably not cloning your local UID."
+fi
+
+demimod 775 /config
+demimod 775 /results
+demimod -R 775 /root
+demimod -R 775 /workspace
+
 echo "-------------------------------------------------------------------"
 echo "Changing pwd to /root"
 cd /root
@@ -25,23 +57,3 @@ else
     exit 1
 fi
 
-# Noisy chown alias to handle read-only/remote volumes
-cat <<-EOF >/usr/bin/demiown
-#!/bin/bash
-chown "\$@" || printf '**** Permissions to $2 could not be set. This is probably because your volume mounts are remote or read-only. ****\n**** The app may not work properly. ****\n'
-EOF
-chmod +x /usr/bin/demiown
-
-cat <<-EOF >/usr/bin/demimod
-#!/bin/bash
-chmod "\$@" || printf '**** Permissions to $2 could not be set. This is probably because your volume mounts are remote or read-only. ****\n**** The app may not work properly. ****\n'
-EOF
-chmod +x /usr/bin/demimod
-
-demiown itk:itk /config
-demiown itk:itk /results
-demiown -R itk:itk /root
-
-demimod 775 /config
-demimod 775 /results
-demimod -R 775 /root
diff --git a/config b/config
index 76dce0191c9904cee8a8486d041d684a3d2a3eec..38b4aad2a46567b7e1cb627b6dd16166cbb9a53b 100755
--- a/config
+++ b/config
@@ -8,7 +8,6 @@ set_additional_envvars() {
   API_PORT=5009
   UI_HOSTPORT=5089
   OPTO_BASE_IMAGE=${GL_REGISTRY}/${GL_ROOTGROUP}/${GL_SUBGROUP}/itk-demo-optoboard/opto-base-image:latest
-  API_IMAGE=${GL_REGISTRY}/${GL_ROOTGROUP}/${GL_SUBGROUP}/itk-demo-optoboard/itk-demo-optoboard-api:latest
 
   # GL_PROJECTID=123155
   
@@ -33,7 +32,6 @@ write_additional_dotenv() {
   say "Additional ${1:-.}/.env"
 cat <<-EOF >> ${1:-.}/.env || true
 OPTO_BASE_IMAGE=${OPTO_BASE_IMAGE}
-API_IMAGE=${API_IMAGE}
 CONFIGDB_API_KEY=${CONFIGDB_API_KEY}
 RABBITMQ_IMAGE=${RABBITMQ_IMAGE}
 RABBITMQ_KEY=${RABBITMQ_KEY}
diff --git a/example/docker-compose.yml b/example/docker-compose.yml
old mode 100644
new mode 100755
index a094375fe8ade2fdb51614daf2fc2fa035abb2f7..558c2ced2003650ae252d3d894e4d49c79295a4d
--- a/example/docker-compose.yml
+++ b/example/docker-compose.yml
@@ -1,5 +1,3 @@
-version: "3.9"
-
 networks:
   deminet:
     name: deminet
@@ -7,7 +5,7 @@ networks:
 
 services:
   api:
-    image: gitlab-registry.cern.ch/atlas-itk-pixel-systemtest/itk-demo-sw/itk-demo-optoboard/itk-demo-optoboard-api:demi-6
+    image: gitlab-registry.cern.ch/atlas-itk-pixel-systemtest/itk-demo-sw/itk-demo-optoboard/itk-demo-optoboard-api:demi-7
     container_name: optoboard-api
     depends_on:
       - worker
@@ -20,6 +18,7 @@ services:
       - API_WORKERS=4
       - PUID=${PUID}
       - PGID=${PGID}
+      - DEMI_ADD_ITK_USER=1
       - SR_URL=http://${HOST}:5111/api
       - RUNKEY_UI_URL_KEY=demi/${STACK}/itk-demo-configdb/runkey-ui/url
     labels:
@@ -36,7 +35,7 @@ services:
       - deminet
 
   worker:
-    image: gitlab-registry.cern.ch/atlas-itk-pixel-systemtest/itk-demo-sw/itk-demo-optoboard/itk-demo-optoboard-api:demi-6
+    image: gitlab-registry.cern.ch/atlas-itk-pixel-systemtest/itk-demo-sw/itk-demo-optoboard/itk-demo-optoboard-api:demi-7
     container_name: optoboard-worker
     depends_on:
       - rabbitmq
@@ -49,11 +48,12 @@ services:
       - WORKSPACE=/workspace
       - PUID=${PUID}
       - PGID=${PGID}
+      - DEMI_ADD_ITK_USER=1
       - TX_PORT=12340
       - RX_PORT=12350
       - TX_TAG=17
       - INTERFACE=optoboard-worker # use the name of the optoboard worker container (or its IP address) when using lpgbt-com, the same but for the felix container for ic-over-netio; else provide IP address
-      - RX_TAG=25
+      - RX_TAG=29
       - SR_URL=http://${HOST}:5111/api
       - FLX_URL_KEY=demi/${STACK}/itk-demo-optoboard/felix/url
       - RUNKEY_UI_URL_KEY=demi/${STACK}/itk-demo-configdb/runkey-ui/url
@@ -95,7 +95,7 @@ services:
 
   ui:
     build: .
-    image: gitlab-registry.cern.ch/atlas-itk-pixel-systemtest/itk-demo-sw/itk-demo-optoboard/itk-demo-optoboard-ui:demi-6
+    image: gitlab-registry.cern.ch/atlas-itk-pixel-systemtest/itk-demo-sw/itk-demo-optoboard/itk-demo-optoboard-ui:demi-7
     container_name: optoboard-ui
     ports:
       - 5089:80
@@ -114,7 +114,7 @@ services:
       - demi.${STACK}.itk-demo-optoboard.ui.category=Microservice-UI
 
   felix:
-    image: gitlab-registry.cern.ch/atlas-itk-pixel-systemtest/itk-demo-sw/itk-demo-felix/api:05-00-04-rm5-el9-demi-10
+    image: gitlab-registry.cern.ch/atlas-itk-pixel-systemtest/itk-demo-sw/itk-demo-felix/api:05-00-04-rm5-el9-demi-12
     restart: unless-stopped
     container_name: felix
     command: ["with-contenv", "bash", "--login", "-c", "reflex init && reflex run"]
@@ -317,7 +317,7 @@ services:
       - ${PWD}/configs:/config/workspace
 
   yarr:
-    image: gitlab-registry.cern.ch/atlas-itk-pixel-systemtest/itk-demo-sw/itk-demo-daqapi/base:YARR-v1.5.1-FELIX-05-00-03-rm5-el9-demi-1
+    image: gitlab-registry.cern.ch/yarr/yarr:v1.5.2
     container_name: yarr
     tty: true    
     restart: unless-stopped
@@ -327,7 +327,8 @@ services:
     volumes:
       - ./configs:/configs
       - ./data:/data
-      - /tmp/bus:/bus
+      - ${PWD}/.shared_volumes/bus:/bus
+      - ${PWD}:/workspace
     networks:
       - deminet
     labels:
diff --git a/opto-base-image/Dockerfile b/opto-base-image/Dockerfile
index 6b2d483356bbae7e0aaf7ab915109839fa65050d..a89f0ee4a48786b4edf0d0c8129e60e34a353982 100644
--- a/opto-base-image/Dockerfile
+++ b/opto-base-image/Dockerfile
@@ -20,14 +20,15 @@ COPY lpgbt-com-build /root/lpgbt-com-build
 
 
 RUN dnf -y install pip git && \
+    pip install pyconfigdb --index-url https://gitlab.cern.ch/api/v4/groups/33370/-/packages/pypi/simple && \
     PYTHON_VERSION_SHORT=$(python3 --version 2>&1 | awk '{print $2}' | cut -d '.' -f 1,2 | tr -d '.') && \
     machine_architecture=$(uname -m) && \
-    cp /root/lpgbt-com-build/lpgbtcom.cpython-${PYTHON_VERSION_SHORT}-${machine_architecture}-linux-gnu.so /usr/lib64/python3.9/site-packages/ && \
+    cp /root/lpgbt-com-build/lpgbtcom.cpython-${PYTHON_VERSION_SHORT}-${machine_architecture}-linux-gnu.so /venv/lib64/python3.9/site-packages/ && \
     cp /root/lpgbt-com-build/liblpgbt-com.so /felix-05-00-04-rm5-stand-alone/x86_64-el9-gcc13-opt/lib && \
     # cp /root/lpgbt-com-build/x86_64-el9-gcc13-opt/lib/lpgbtcom.so /usr/lib64/python3.9/site-packages/ && \
     # cp /root/lpgbt-com-build/x86_64-el9-gcc13-opt/lib/liblpgbt-com.so /felix-05-00-03-rm5-stand-alone/x86_64-el9-gcc13-opt/lib && \
     # cp /root/ic-over-netio-next-build/libitk_ic_over_netio_next.so /usr/lib64/python3.9/site-packages/ && \
-    cp /root/ic-over-netio-build/libic_comms.cpython-${PYTHON_VERSION_SHORT}-${machine_architecture}-linux-gnu.so /usr/lib64/python3.9/site-packages/
+    cp /root/ic-over-netio-build/libic_comms.cpython-${PYTHON_VERSION_SHORT}-${machine_architecture}-linux-gnu.so /venv/lib64/python3.9/site-packages/
 
 # environment variables
 
@@ -45,8 +46,7 @@ ENV PS1="[Docker] $(whoami)@$(hostname):$(pwd)\\$ " \
 RUN python3 -m pip install optoboard-felix --index-url https://gitlab.cern.ch/api/v4/projects/113584/packages/pypi/simple  && \
     python3 -m pip install service-registry --index-url https://gitlab.cern.ch/api/v4/projects/145742/packages/pypi/simple  && \
     python3 -m pip install config-checker --index-url https://gitlab.cern.ch/api/v4/projects/163911/packages/pypi/simple && \
-    echo pip show optoboard-felix &&\
-    python3 -m pip install progress    
+    echo pip show optoboard-felix
     
 
 
diff --git a/opto-base-image/docker-compose.yml b/opto-base-image/docker-compose.yml
index d7c253fb7d7930b13d3856f5fa9fc3f553b359fa..cf565ad15c5544676e7e650ca987f30b9567a21b 100644
--- a/opto-base-image/docker-compose.yml
+++ b/opto-base-image/docker-compose.yml
@@ -14,7 +14,7 @@ services:
       context: .
       dockerfile: Dockerfile
     container_name: optoboard-container
-    image: gitlab-registry.cern.ch/atlas-itk-pixel-systemtest/itk-demo-sw/containers/optoboard-container/optoboard-container:latest
+    image: gitlab-registry.cern.ch/atlas-itk-pixel-systemtest/itk-demo-sw/itk-demo-optoboard/opto-base-image:latest
     environment:
       - PUID=1001
       - PGID=1001