diff --git a/APSCT_I2C.py b/APSCT_I2C.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ac297b281d38a6aa7f8264db1e8b5d534e3e736
--- /dev/null
+++ b/APSCT_I2C.py
@@ -0,0 +1,61 @@
+"""
+Copyright 2022 Stichting Nederlandse Wetenschappelijk Onderzoek Instituten,
+ASTRON Netherlands Institute for Radio Astronomy
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+
+ Created: 2022-12-07
+This file contains the definitions of the APSPU registers etc.
+
+
+"""
+#
+# I2C address, registers and ports for APSCT
+# Created: 2023-01-06
+#
+
+#
+# Power supplies
+#
+
+PWR_LOCATIONS = {"INPUT":  0,
+                 "PLL_160M": 1,
+                 "PLL_200M": 2,
+                 "DIST_A": 3,
+                 "DIST_B": 4,
+                 "DIST_C": 5,
+                 "DIST_D": 6,
+                 "CTRL": 7}
+
+PWR_VOUT = {"INPUT":  3.3,
+            "PLL_160M": 3.3,
+            "PLL_200M": 3.3,
+            "DIST_A": 3.3,
+            "DIST_B": 3.3,
+            "DIST_C": 3.3,
+            "DIST_D": 3.3,
+            "CTRL": 3.3}
+
+#
+# PLL constants / pin locations
+#
+CS = 6
+SCLK = 4
+SDO = 5
+SDI = 7
+
+PLL_200M = 0x20
+PLL_160M = 0x21
+
+#
+# Central I2C Devices
+#
+EEPROM = 0x50
diff --git a/apsct_lib.py b/apsct_lib.py
index a3778865d00607db5074a92427a2d607dc78eaeb..6eb00df0a25cc44530364096bd17f9ccd52b5eca 100644
--- a/apsct_lib.py
+++ b/apsct_lib.py
@@ -15,6 +15,7 @@ Set APSCT_CLK
 
 """
 import sys
+import APSCT_I2C
 import time
 sys.path.insert(0, '.')
 import os
@@ -26,26 +27,17 @@ else:
 I2CBUSNR = 5
 sleep_time = 0.15
 
-EEPROM = 0x50
-PLL_200M = 0x20
-PLL_160M = 0x21
-
-CS = 6
-SCLK = 4
-SDO = 5
-SDI = 7
-
-
 
 class ApsctClass:
     #
     # Toplevel class that contrains all parts of the APSCT
     #
-    def __init__(self):
+    def __init__(self, frequency="200MHz"):
         self.status = False
+        self.frequency = frequency
         self.eeprom = EepromClass()
-        self.pll_200 = PllClass(PLL_200M)
-        self.pll_160 = PllClass(PLL_160M)
+        self.pll_200 = PllClass("200MHz")
+        self.pll_160 = PllClass("160MHz")
         self.sensors = ApsctSensors()
 
     def read_IO_expanderis(self):
@@ -76,13 +68,13 @@ class ApsctClass:
         I2C_IO_device_B = I2C(0x21, BUSNR=I2CBUSNR)
         I2C_IO_device_B.write_bytes(0x06, 0x2C)  # '0' is output
         if state:
-            bits_to_set_A1 = 0x02 | (1 << CS) | (0 << SCLK) | (0 << SDI)
+            bits_to_set_A1 = 0x02 | (1 << APSCT_I2C.CS) | (0 << APSCT_I2C.SCLK) | (0 << APSCT_I2C.SDI)
             bits_to_set_A2 = 0x04
-            bits_to_set_B1 = 0x02 | (1 << CS) | (0 << SCLK) | (0 << SDI)
+            bits_to_set_B1 = 0x02 | (1 << APSCT_I2C.CS) | (0 << APSCT_I2C.SCLK) | (0 << APSCT_I2C.SDI)
         else:
-            bits_to_set_A1 = 0x00 | (1 << CS) | (0 << SCLK) | (0 << SDI)
+            bits_to_set_A1 = 0x00 | (1 << APSCT_I2C.CS) | (0 << APSCT_I2C.SCLK) | (0 << APSCT_I2C.SDI)
             bits_to_set_A2 = 0x00
-            bits_to_set_B1 = 0x00 | (1 << CS) | (0 << SCLK) | (0 << SDI)
+            bits_to_set_B1 = 0x00 | (1 << APSCT_I2C.CS) | (0 << APSCT_I2C.SCLK) | (0 << APSCT_I2C.SDI)
         if DEBUG:
             stri = "Bits to reg 0 0x{0:x}".format(bits_to_set_A1)
             print(stri)
@@ -90,32 +82,47 @@ class ApsctClass:
         I2C_IO_device_A.write_bytes(0x03, bits_to_set_A2)
         I2C_IO_device_B.write_bytes(0x02, bits_to_set_B1)
 
-    def set_apsct(self, state):
+    def set_apsct(self):
         #
         # set APSCT to 200MHz, 160MHz or off
         #
-        if state == "200MHz":
+        if self.frequency == "200MHz":
             self.power(True)
             self.pll_200.setup_pll()
-        elif state == "160MHz":
+        elif self.frequency == "160MHz":
             self.power(True)
             self.pll_160.setup_pll()
         else:
             self.power(False)
 
+    def check_apsct(self):
+        result = self.sensors.check_values()
+        if self.frequency == "200MHz":
+            self.pll_200.read_lock()
+            lock = self.pll_200.lock
+            result = result & lock
+        elif self.frequency == "160MHz":
+            self.pll_160.read_lock()
+            lock = self.pll_160.lock
+            result = result & lock
+        else:
+            result = result
+        return result
+
 
 class PllClass:
     #
     # Toplevel class that contrains all parts of the PLL
     #
-    def __init__(self, address=0x20):
+    def __init__(self, frequency="200MHz"):
         self.status = False
-        self.i2c_address = address
-        self.dev_i2c_pll = I2C(self.i2c_address, BUSNR=I2CBUSNR)
-        if address == 0x20:
-            self.frequency = '200MHz'
+        self.lock = False
+        self.frequency = frequency
+        if self.frequency == "160MHz":
+            self.i2c_address = APSCT_I2C.PLL_160M
         else:
-            self.frequency = '160MHz'
+            self.i2c_address = APSCT_I2C.PLL_200M
+        self.dev_i2c_pll = I2C(self.i2c_address, BUSNR=I2CBUSNR)
 
     def Write_byte_PLL(self, reg_address, wr_data):
         #
@@ -131,19 +138,19 @@ class PllClass:
             print(stri)
         data = (reg_address << 9) + (pll_rw << 8) + wr_data
         bit_array = "{0:{fill}16b}".format(data, fill='0')
-        self.dev_i2c_pll.write_bytes(0x02, 0x02 | (0x1 << CS))
+        self.dev_i2c_pll.write_bytes(0x02, 0x02 | (0x1 << APSCT_I2C.CS))
         for bit in bit_array:
             for clk in range(2):
-                Write_data = 0x02 | (0 << CS) | (clk << SCLK) | (int(bit) << SDI)
+                Write_data = 0x02 | (0 << APSCT_I2C.CS) | (clk << APSCT_I2C.SCLK) | (int(bit) << APSCT_I2C.SDI)
                 self.dev_i2c_pll.write_bytes(0x02, Write_data)
         for clk in range(2):
-            Write_data = 0x02 | (0 << CS) | (clk << SCLK)
+            Write_data = 0x02 | (0 << APSCT_I2C.CS) | (clk << APSCT_I2C.SCLK)
             self.dev_i2c_pll.write_bytes(0x02, Write_data)
         for clk in range(2):
-            Write_data = 0x02 | (1 << CS) | (clk << SCLK)
+            Write_data = 0x02 | (1 << APSCT_I2C.CS) | (clk << APSCT_I2C.SCLK)
             self.dev_i2c_pll.write_bytes(0x02, Write_data)
 
-        Write_data = 0x02 | (1 << CS) | (0 << SCLK) | (0 << SDI)
+        Write_data = 0x02 | (1 << APSCT_I2C.CS) | (0 << APSCT_I2C.SCLK) | (0 << APSCT_I2C.SDI)
         self.dev_i2c_pll.write_bytes(0x02, Write_data)
 
     def Read_byte_PLL(self, reg_address, nof_bytes=1):
@@ -156,24 +163,25 @@ class PllClass:
         bit_array = "{0:{fill}8b}".format(data, fill='0')
         for bit in bit_array:
             for clk in range(2):
-                Write_data = 0x02 | (0 << CS) | (clk << SCLK) | (int(bit) << SDI)
+                Write_data = 0x02 | (0 << APSCT_I2C.CS) | (clk << APSCT_I2C.SCLK) | (int(bit) << APSCT_I2C.SDI)
                 self.dev_i2c_pll.write_bytes(0x02, Write_data)
                 sleep(sleep_time)
         read_bit = ''
         for cnt in range(8*nof_bytes):
             for clk in [0, 1]:  # Read after rizing edge
-                Write_data = 0x02 | (clk << SCLK) | (int(bit_array[-1]) << SDI)
+                Write_data = 0x02 | (clk << APSCT_I2C.SCLK) | (int(bit_array[-1]) << APSCT_I2C.SDI)
                 self.dev_i2c_pll.write_bytes(0x02, Write_data)
             ret_ack, ret_value = self.dev_i2c_pll.read_bytes(0x00, 1)
             if ret_ack:
-                read_bit += str((int(ret_value, 16) >> SDO) & 0x01)
+                read_bit += str((int(ret_value, 16) >> APSCT_I2C.SDO) & 0x01)
             else:
                 print("ACK nok")
-        Write_data = 0x02 | (1 << CS) | (0 << SCLK) | (0 << SDI)
+        Write_data = 0x02 | (1 << APSCT_I2C.CS) | (0 << APSCT_I2C.SCLK) | (0 << APSCT_I2C.SDI)
         self.dev_i2c_pll.write_bytes(0x02, Write_data)
-        stri = "Read back at address 0x{0:{fill}2x} result : 0x{1:{fill}2x} ".format(reg_address,
-                                                                                     int(read_bit, 2), fill='0')
-        print(stri)
+        if DEBUG:
+            stri = "Read back at address 0x{0:{fill}2x} result : 0x{1:{fill}2x} ".format(reg_address,
+                                                                                         int(read_bit, 2), fill='0')
+            print(stri)
         return read_bit
 
     def setup_pll(self):
@@ -223,16 +231,22 @@ class PllClass:
         #
         # Read lock status
         #
-        ret_value = self.Read_byte_PLL(0x00, nof_bytes = 1)
-        status_pll = int(ret_value,2)
+        ret_value = self.Read_byte_PLL(0x00, nof_bytes=1)
+        status_pll = int(ret_value, 2)
         if status_pll == 0x04:
-            print("PLL in lock")
+            self.lock = True
+            if DEBUG:
+                print("PLL in lock")
         elif (status_pll & 0x10) > 0:
-            print("Not Locked --> No 10 MHz ref")
+            self.lock = False
+            if DEBUG:
+                print("Not Locked --> No 10 MHz ref")
         else:
-            print("Not locked --> PLL Error")
+            self.lock = False
+            if DEBUG:
+                print("Not locked --> PLL Error")
 
-    def read_lol(self, pll_frequency='200MHz'):
+    def read_lol(self):
         #
         # Read loss of lock status
         #
@@ -245,9 +259,9 @@ class PllClass:
 
         ack, ret_value = I2C_IO_device_B.read_bytes(0x01, 1)
         status_reg = int(ret_value, 16)
-        if (pll_frequency == '200MHz') & ((status_reg & 0x10) > 0):
+        if (self.frequency == '200MHz') & ((status_reg & 0x10) > 0):
             print("200MHz has lost lock")
-        if ((status_reg & 0x20) > 0) & (pll_frequency == '160MHz'):
+        if ((status_reg & 0x20) > 0) & (self.frequency == '160MHz'):
             print("160MHz has last lock")
         ack, ret_value = I2C_IO_device_A.read_bytes(0x01, 1)
         old_reg = int(ret_value, 16)
@@ -264,7 +278,7 @@ class EepromClass:
         #
         # All monitor. read and write functions for the EEPROM
         #
-        self.dev_i2c_eeprom = I2C(EEPROM)
+        self.dev_i2c_eeprom = I2C(APSCT_I2C.EEPROM)
         self.dev_i2c_eeprom.bus_nr = I2CBUSNR
 
     def write_eeprom(self, data="APSPU", address=0):
@@ -301,7 +315,6 @@ class EepromClass:
         else:
             ret_ack, ret_value = self.dev_i2c_eeprom.read_bytes(address, nof_bytes)
             ret_value = bytes.fromhex(ret_value[:nof_bytes * 2])
-            #print(" ret value = {}".format(ret_value))
             str_return = ret_value.decode('UTF-8')
             return str_return
 
@@ -334,12 +347,39 @@ class ApsctSensors:
         #
         self.dev_i2c_sensor = I2C(0x74)
         self.dev_i2c_sensor.bus_nr = I2CBUSNR
+        self.power_supplies = list(APSCT_I2C.PWR_LOCATIONS.keys())
+        self.voltages = {}
+        self.temperature = 9999
 
     def apsct_sensors(self):
         for sens_line in range(7):
             self.read_voltage(sens_line)
         self.read_temp()
 
+    def read_all_voltages(self):
+        for pwr in self.power_supplies:
+            self.voltages[pwr] = self.read_voltage(APSCT_I2C.PWR_LOCATIONS[pwr])
+        return True
+
+    def check_values(self):
+        #
+        # Function to check sensor values
+        #
+        # return result, True when OK, False in case of error
+        #
+        result = True
+        self.read_all_voltages()
+        self.read_temp()
+        for pwr in self.power_supplies:
+            expected = APSCT_I2C.PWR_VOUT[pwr]
+            if 0.9*expected > self.voltages[pwr] > 1.1*expected:
+                result = False
+                print(f"Error {pwr} expected {expected} V read {self.voltages[pwr]} V")
+        if 15 > self.temperature > 50:
+            result = False
+            print(f"Error temperature read {self.temperature} °C")
+        return result
+
     def read_voltage(self, input_channel=0):
         #
         # Function to read a voltages of APSCT
@@ -347,6 +387,7 @@ class ApsctSensors:
         # input_channel = sens port
         # return value
         #
+        voltage = 9999
         Vref = 3.0
         one_step = Vref/(2**16)
         channel_select_word = 0xB0 | ((input_channel % 2) << 3) | ((input_channel >> 1) & 0x7)
@@ -368,6 +409,7 @@ class ApsctSensors:
             voltage = ((4.7+2.2)/2.2)*2*voltage
             string = "Voltage sens line {1} is {0:.4f} V".format(voltage, input_channel)
             print(string)
+        return voltage
 
     def read_temp(self):
         #
@@ -384,9 +426,7 @@ class ApsctSensors:
         if ret_ack:
             raw_value = (int(ret_value, 16) & 0x1FFFFF) >> 6
             temperature_K = (raw_value/temp_slope)
-            temperature = temperature_K-273
-            stri = "Temperature : {0:.2f} gr. C".format(temperature)
-            print(stri)
+            self.temperature = temperature_K-273
         else:
-            print("Error reading tempeature")
-
+            self.temperature = 9999
+        return self.temperature
diff --git a/production_apsct.py b/production_apsct.py
index 10d90a4341227e4d521cfc119ad3b10c694bbe02..97fb0011d2a2dde0a4b86b93db696942ec43843a 100644
--- a/production_apsct.py
+++ b/production_apsct.py
@@ -11,49 +11,60 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 
-Set APSCT_CLK
+Check APSCT_CLK
 
 """
-import time
 import apsct_lib
+import sys
 
-DEBUG = False
-SET_PLL = True
-READ_LOCK = True
 READ_ALL = True
-CHECK_EEPROM = True
-PWR_RST = False  # True
-READ_SENSOR = True
-READ_REGS = False  # True
 
 CLK_FREQ = '200MHz'
 
-apsct = apsct_lib.ApsctClass()
-apsct.sensors.read_temp()
+if len(sys.argv) < 2:
+    print("Production_apsct.py <ASTRON NR> <Serial number>")
+    print("e.g. python3 production_apsct.py 2023-01 1234")
+    exit()
 
-if CHECK_EEPROM:
-    apsct.eeprom.wr_rd_eeprom()
+apsct = apsct_lib.ApsctClass(CLK_FREQ)
 
-if PWR_RST:
-    apsct.power(False)
-    time.sleep(10)
-    apsct.power(True)
+print*("Check APSCT in 200MHz mode")
+apsct.frequency = "200MHz"
+apsct.set_apsct()
+apsct.pll_200.read_lock()
+apsct.pll_200.read_lol()
+apsct.pll_160.read_lock()
+apsct.pll_160.read_lol()
+apsct.sensors.apsct_sensors()
 
-if SET_PLL:
-    apsct.set_apsct(CLK_FREQ)
+print*("Check APSCT in 160MHz mode")
+apsct.frequency = "160MHz"
+apsct.set_apsct()
+apsct.pll_200.read_lock()
+apsct.pll_200.read_lol()
+apsct.pll_160.read_lock()
+apsct.pll_160.read_lol()
+apsct.sensors.apsct_sensors()
 
-if READ_LOCK:
-    apsct.pll_200.read_lock()
-
-if READ_REGS:
-    apsct.pll_200.read_all_regs_pll()
+print*("Check APSCT in off mode")
+apsct.frequency = "OFF"
+apsct.set_apsct()
+apsct.pll_200.read_lock()
+apsct.pll_200.read_lol()
+apsct.pll_160.read_lock()
+apsct.pll_160.read_lol()
+apsct.sensors.apsct_sensors()
 
 if READ_ALL:
     apsct.pll_200.read_all_regs_pll()
 #    apsct.pll_160.read_all_regs_pll()
     apsct.read_IO_expanderis()
 
-if READ_SENSOR:
-    apsct.sensors.apsct_sensors()
-
-apsct.pll_200.read_lol(CLK_FREQ)
+if apsct.check_apsct():
+    apsct_id = "APSCT-" + sys.argv[1]
+    serial = sys.argv[2]
+    rw_ok = apsct.eeprom.wr_rd_eeprom(apsct_id, address=0)
+    if rw_ok:
+        rw_ok = apsct.eeprom.wr_rd_eeprom(serial, address=0x20)
+    if not rw_ok:
+        print("EEPROM Error")
\ No newline at end of file