diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index edd7c5afd7afb360568000de3b720df468cefb95..de8a85e3ba87d0e659d0ecb96e6457e6c48fab46 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -101,6 +101,11 @@ docker_build_image_all:
     - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-sst latest
     - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-unb2 latest
     - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-xst latest
+    - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-temperature-manager latest
+    - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh archiver-timescale latest
+    - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh hdbppts-cm latest
+    - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh hdbppts-es latest
+
 docker_build_image_elk:
   extends: .base_docker_images
   rules:
@@ -491,6 +496,66 @@ docker_build_image_device_xst:
   script:
 #    Do not remove 'bash' or statement will be ignored by primitive docker shell
     - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-xst $tag
+docker_build_image_device_temperature_manager:
+  extends: .base_docker_images
+  rules:
+    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
+      when: never
+    - if: '$CI_COMMIT_TAG != null'
+      when: never
+    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
+      when: never
+    - changes:
+      - docker-compose/device-temperature-manager.yml
+      - docker-compose/lofar-device-base/*
+  script:
+#    Do not remove 'bash' or statement will be ignored by primitive docker shell
+    - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-temperature-manager $tag
+docker_build_image_archiver_timescale:
+  extends: .base_docker_images
+  rules:
+    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
+      when: never
+    - if: '$CI_COMMIT_TAG != null'
+      when: never
+    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
+      when: never
+    - changes:
+      - docker-compose/archiver-timescale.yml
+      - docker-compose/timescaledb/*
+  script:
+#    Do not remove 'bash' or statement will be ignored by primitive docker shell
+    - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh archiver-timescale $tag
+docker_build_image_hdbppts_cm:
+  extends: .base_docker_images
+  rules:
+    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
+      when: never
+    - if: '$CI_COMMIT_TAG != null'
+      when: never
+    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
+      when: never
+    - changes:
+      - docker-compose/archiver-timescale.yml
+      - docker-compose/tango-archiver-ts/*
+  script:
+#    Do not remove 'bash' or statement will be ignored by primitive docker shell
+    - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh hdbppts-cm $tag
+docker_build_image_hdbppts_es:
+  extends: .base_docker_images
+  rules:
+    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
+      when: never
+    - if: '$CI_COMMIT_TAG != null'
+      when: never
+    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
+      when: never
+    - changes:
+      - docker-compose/archiver-timescale.yml
+      - docker-compose/tango-archiver-ts/*
+  script:
+#    Do not remove 'bash' or statement will be ignored by primitive docker shell
+    - bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh hdbppts-es $tag
 newline_at_eof:
   stage: linting
   before_script:
diff --git a/CDB/LOFAR_ConfigDb.json b/CDB/LOFAR_ConfigDb.json
index 21a93809a8f8df10ccf4ecfaeb3ef8d926ef9b83..9c243aab268d9ca13f37bfe3d7af9cfbba8222de 100644
--- a/CDB/LOFAR_ConfigDb.json
+++ b/CDB/LOFAR_ConfigDb.json
@@ -42,6 +42,13 @@
                 }
             }
         },
+        "TemperatureManager": {
+            "STAT": {
+                "TemperatureManager": {
+                    "STAT/TemperatureManager/1": {}
+                }
+            }
+        },
         "TileBeam": {
             "STAT": {
                 "TileBeam": {
diff --git a/CDB/stations/simulators_ConfigDb.json b/CDB/stations/simulators_ConfigDb.json
index 59fcdee54cef6d9947419e839805e9851c539f65..6afb6b21adb00239edf53241dfe4b515cad0f35a 100644
--- a/CDB/stations/simulators_ConfigDb.json
+++ b/CDB/stations/simulators_ConfigDb.json
@@ -116,6 +116,16 @@
                 }
             }
         },
+        "TemperatureManager": {
+            "STAT": {
+                "TemperatureManager": {
+                    "STAT/TemperatureManager/1": {
+                        "properties": {
+                        }
+                    }
+                }
+            }
+        },
         "RECV": {
             "STAT": {
                 "RECV": {
diff --git a/docker-compose/device-temperature-manager.yml b/docker-compose/device-temperature-manager.yml
new file mode 100644
index 0000000000000000000000000000000000000000..cf1ac02fd36bbf0a7ef63ba05979e8702fad8985
--- /dev/null
+++ b/docker-compose/device-temperature-manager.yml
@@ -0,0 +1,42 @@
+#
+# Requires:
+#   - lofar-device-base.yml
+#
+version: '2'
+
+volumes:
+  iers-data: {}
+
+services:
+  device-temperature-manager:
+    image: device-temperature-manager
+    # build explicitly, as docker-compose does not understand a local image
+    # being shared among services.
+    build:
+        context: ..
+        dockerfile: docker-compose/lofar-device-base/Dockerfile
+        args:
+            SOURCE_IMAGE: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}-tango-itango:${TANGO_ITANGO_VERSION}
+    container_name: ${CONTAINER_NAME_PREFIX}device-temperature-manager
+    logging:
+      driver: "json-file"
+      options:
+        max-size: "100m"
+        max-file: "10"
+    networks:
+      - control
+    ports:
+      - "5716:5716" # unique port for this DS
+    extra_hosts:
+      - "host.docker.internal:host-gateway"
+    volumes:
+      - ..:/opt/lofar/tango:rw
+    environment:
+      - TANGO_HOST=${TANGO_HOST}
+    working_dir: /opt/lofar/tango
+    entrypoint:
+      - bin/start-ds.sh
+      # configure CORBA to _listen_ on 0:port, but tell others we're _reachable_ through ${HOSTNAME}:port, since CORBA
+      # can't know about our Docker port forwarding
+      - l2ss-temperature-manager TemperatureManager STAT -v -ORBendPoint giop:tcp:0:5716 -ORBendPointPublish giop:tcp:${HOSTNAME}:5716
+    restart: unless-stopped
diff --git a/docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/01-devices.py b/docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/01-devices.py
index d9cdd0e945bc0f0c54eacedc767c364e7336f89e..ba7ce483e7aed1ce1c1b47fcb1b34a5eead09501 100644
--- a/docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/01-devices.py
+++ b/docker-compose/jupyter/ipython-profiles/stationcontrol-jupyter/startup/01-devices.py
@@ -13,6 +13,7 @@ beamlet = DeviceProxy("STAT/Beamlet/1")
 digitalbeam = DeviceProxy("STAT/DigitalBeam/1")
 antennafield = DeviceProxy("STAT/AntennaField/1")
 docker = DeviceProxy("STAT/Docker/1")
+temperaturemanager = DeviceProxy("STAT/TemperatureManager/1")
 
 # Put them in a list in case one wants to iterate
-devices = [apsct, apspu, recv, sdp, sst, xst, unb2, boot, tilebeam, beamlet, digitalbeam, antennafield, docker]
+devices = [apsct, apspu, recv, sdp, sst, xst, unb2, boot, tilebeam, beamlet, digitalbeam, antennafield, temperaturemanager, docker]
diff --git a/docker-compose/tango-prometheus-exporter/code/tango-prometheus-client.py b/docker-compose/tango-prometheus-exporter/code/tango-prometheus-client.py
index 489d5282acff1618d2c436a741f1a3c5d9f6db3b..d171d9219e2bb3043f6c8be0d91a32bd8a9fb807 100644
--- a/docker-compose/tango-prometheus-exporter/code/tango-prometheus-client.py
+++ b/docker-compose/tango-prometheus-exporter/code/tango-prometheus-client.py
@@ -64,13 +64,12 @@ class ArchiverPolicy(object):
         return sorted(list(attributes))
 
 class CustomCollector(object):
-    def __init__(self, station, config, proxy_timeout=250):
+    def __init__(self, config, station, proxy_timeout=250):
         self.station = station
         self.policy = ArchiverPolicy(config)
         self.proxy_timeout = proxy_timeout
 
-    @staticmethod
-    def _to_metric(dev, attr_info, x, y, idx, value):
+    def _to_metric(self, dev, attr_info, x, y, idx, value):
         """ Convert the given values to a (labels, value) pair, used to construct a Metric. """
 
         if attr_info.data_type in [ArgType.DevShort, ArgType.DevLong, ArgType.DevUShort, ArgType.DevULong, ArgType.DevLong64, ArgType.DevULong64, ArgType.DevInt, ArgType.DevFloat, ArgType.DevDouble]:
diff --git a/sbin/run_integration_test.sh b/sbin/run_integration_test.sh
index fd18a0ee309d322c6de8e6bf12c8df9c183b235c..7e0cf3b27ba111077c5739ce5fd832b4b6ea6e05 100755
--- a/sbin/run_integration_test.sh
+++ b/sbin/run_integration_test.sh
@@ -20,7 +20,7 @@ sleep 1 # dsconfig container must be up and running...
 # shellcheck disable=SC2016
 echo '/usr/local/bin/wait-for-it.sh ${TANGO_HOST} --strict --timeout=300 -- true' | make run dsconfig bash -
 
-DEVICES="device-boot device-apsct device-apspu device-sdp device-recv device-sst device-unb2 device-xst device-beamlet device-digitalbeam device-tilebeam device-pdu device-antennafield"
+DEVICES="device-boot device-apsct device-apspu device-sdp device-recv device-sst device-unb2 device-xst device-beamlet device-digitalbeam device-tilebeam device-pdu device-antennafield device-temperature-manager"
 SIMULATORS="sdptr-sim recv-sim unb2-sim apsct-sim apspu-sim"
 
 # Build only the required images, please do not build everything that makes CI
diff --git a/tangostationcontrol/docs/source/devices/temperature-manager.rst b/tangostationcontrol/docs/source/devices/temperature-manager.rst
new file mode 100644
index 0000000000000000000000000000000000000000..c4f919377d5fbcb79338b0ea28e24c4cbf35c975
--- /dev/null
+++ b/tangostationcontrol/docs/source/devices/temperature-manager.rst
@@ -0,0 +1,4 @@
+temperature-manager
+====================
+
+``temperature_manager == DeviceProxy("STAT/TemperatureManager/1")``
diff --git a/tangostationcontrol/docs/source/index.rst b/tangostationcontrol/docs/source/index.rst
index 263bcd064268839baa452e087f1c732a8ea92ffa..3808637151423688e7b25dd0a50d0e05a0bf3ae3 100644
--- a/tangostationcontrol/docs/source/index.rst
+++ b/tangostationcontrol/docs/source/index.rst
@@ -29,6 +29,7 @@ Even without having access to any LOFAR2.0 hardware, you can install the full st
    devices/recv
    devices/sdp
    devices/sst-xst
+   devices/temperature-manager
    devices/configure
    configure_station
    alerting
diff --git a/tangostationcontrol/setup.cfg b/tangostationcontrol/setup.cfg
index de930c9d399dd5412884f37b3957a698d330b163..1d52727f782ff41dd2e7e75b2d3137314bfdb82f 100644
--- a/tangostationcontrol/setup.cfg
+++ b/tangostationcontrol/setup.cfg
@@ -51,6 +51,7 @@ console_scripts =
     l2ss-statistics-writer = tangostationcontrol.statistics_writer.statistics_writer:main
     l2ss-unb2 = tangostationcontrol.devices.unb2:main
     l2ss-xst = tangostationcontrol.devices.sdp.xst:main
+    l2ss-temperature-manager = tangostationcontrol.devices.temperature_manager:main
 
 # The following entry points should eventually be removed / replaced
     l2ss-cold-start = tangostationcontrol.toolkit.lts_cold_start:main
diff --git a/tangostationcontrol/tangostationcontrol/devices/boot.py b/tangostationcontrol/tangostationcontrol/devices/boot.py
index 6903789744ffe673a21a80949ad000e36e0fa7ce..c14c7476021f18e313463bfe8ac82e86c46ccb25 100644
--- a/tangostationcontrol/tangostationcontrol/devices/boot.py
+++ b/tangostationcontrol/tangostationcontrol/devices/boot.py
@@ -244,6 +244,7 @@ class Boot(lofar_device):
                        "STAT/Beamlet/1",
                        "STAT/TileBeam/1",   # Accesses RECV and Beamlet
                        "STAT/DigitalBeam/1",
+                       "STAT/TemperatureManager/1",
                        "STAT/AntennaField/1",
                       ],
     )
diff --git a/tangostationcontrol/tangostationcontrol/devices/temperature_manager.py b/tangostationcontrol/tangostationcontrol/devices/temperature_manager.py
new file mode 100644
index 0000000000000000000000000000000000000000..c1db80b161524c04be7489e7017ed373ae70c1ff
--- /dev/null
+++ b/tangostationcontrol/tangostationcontrol/devices/temperature_manager.py
@@ -0,0 +1,57 @@
+# -*- coding: utf-8 -*-
+#
+# Distributed under the terms of the APACHE license.
+# See LICENSE.txt for more info.
+
+""" overtemperature managing Device Server for LOFAR2.0
+
+"""
+
+# Additional import
+from tangostationcontrol.common.entrypoint import entry
+from tangostationcontrol.devices.lofar_device import lofar_device
+from tangostationcontrol.common.lofar_logging import device_logging_to_python, log_exceptions
+
+import logging
+
+logger = logging.getLogger()
+
+__all__ = ["TemperatureManager", "main"]
+
+
+@device_logging_to_python()
+class TemperatureManager(lofar_device):
+    # -----------------
+    # Device Properties
+    # -----------------
+
+    # ----------
+    # Attributes
+    # ----------
+
+    # --------
+    # overloaded functions
+    # --------
+
+    def init_device(self):
+        super().init_device()
+
+    @log_exceptions()
+    def configure_for_initialise(self):
+        super().configure_for_initialise()
+
+    @log_exceptions()
+    def configure_for_on(self):
+        super().configure_for_on()
+
+    @log_exceptions()
+    def configure_for_off(self):
+        super().configure_for_off()
+
+
+# ----------
+# Run server
+# ----------
+def main(**kwargs):
+    """Main function of the temperature manager module."""
+    return entry(TemperatureManager, **kwargs)
diff --git a/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_temperature_manager.py b/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_temperature_manager.py
new file mode 100644
index 0000000000000000000000000000000000000000..ea884acf1d7557b1e72f64ee71eee756145f083f
--- /dev/null
+++ b/tangostationcontrol/tangostationcontrol/integration_test/default/devices/test_device_temperature_manager.py
@@ -0,0 +1,16 @@
+
+# -*- coding: utf-8 -*-
+#
+# This file is part of the LOFAR 2.0 Station Software
+#
+#
+#
+# Distributed under the terms of the APACHE license.
+# See LICENSE.txt for more info.
+from .base import AbstractTestBases
+
+class TestTemperatureManager(AbstractTestBases.TestDeviceBase):
+
+    def setUp(self):
+        """Intentionally recreate the device object in each test"""
+        super().setUp("STAT/TemperatureManager/1")