diff --git a/CMake/LofarPackageList.cmake b/CMake/LofarPackageList.cmake
index d20259d674045344a34394e159697f5c9fe45cf2..8d989d87ee796b3e8eab2913c957abb0ddd14ebe 100644
--- a/CMake/LofarPackageList.cmake
+++ b/CMake/LofarPackageList.cmake
@@ -1,7 +1,7 @@
 # - Create for each LOFAR package a variable containing the absolute path to
 # its source directory. 
 #
-# Generated by gen_LofarPackageList_cmake.sh at do 29 okt 2020  7:42:34 CET
+# Generated by gen_LofarPackageList_cmake.sh at ma  2 nov 2020 19:21:07 CET
 #
 #                      ---- DO NOT EDIT ----
 #
@@ -210,6 +210,7 @@ if(NOT DEFINED LOFAR_PACKAGE_LIST_INCLUDED)
   set(TMSSSubtaskSchedulingService_SOURCE_DIR ${CMAKE_SOURCE_DIR}/SAS/TMSS/services/subtask_scheduling)
   set(TMSSFeedbackHandlingService_SOURCE_DIR ${CMAKE_SOURCE_DIR}/SAS/TMSS/services/feedback_handling)
   set(TMSSPostgresListenerService_SOURCE_DIR ${CMAKE_SOURCE_DIR}/SAS/TMSS/services/tmsspglistener)
+  set(TMSSWebSocketService_SOURCE_DIR ${CMAKE_SOURCE_DIR}/SAS/TMSS/services/websocket)
   set(TriggerEmailServiceCommon_SOURCE_DIR ${CMAKE_SOURCE_DIR}/SAS/TriggerEmailService/Common)
   set(TriggerEmailServiceServer_SOURCE_DIR ${CMAKE_SOURCE_DIR}/SAS/TriggerEmailService/Server)
   set(CCU_MAC_SOURCE_DIR ${CMAKE_SOURCE_DIR}/SubSystems/CCU_MAC)
diff --git a/SAS/TMSS/services/CMakeLists.txt b/SAS/TMSS/services/CMakeLists.txt
index 4852da84118b8f28e066538bf383f63e2daaf309..1fc3390c752c22ed5f1492ef131765fed9a837b5 100644
--- a/SAS/TMSS/services/CMakeLists.txt
+++ b/SAS/TMSS/services/CMakeLists.txt
@@ -1,4 +1,5 @@
 lofar_add_package(TMSSSubtaskSchedulingService subtask_scheduling)
 lofar_add_package(TMSSFeedbackHandlingService feedback_handling)
 lofar_add_package(TMSSPostgresListenerService tmsspglistener)
+lofar_add_package(TMSSWebSocketService websocket)
 
diff --git a/SAS/TMSS/services/websocket/CMakeLists.txt b/SAS/TMSS/services/websocket/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..460e356bc2c99121eb41a48fc27fad7d20a51fac
--- /dev/null
+++ b/SAS/TMSS/services/websocket/CMakeLists.txt
@@ -0,0 +1,8 @@
+lofar_package(TMSSSubtaskSchedulingService 0.1 DEPENDS TMSSClient PyCommon pyparameterset PyMessaging)
+
+lofar_find_package(PythonInterp 3.4 REQUIRED)
+
+add_subdirectory(lib)
+add_subdirectory(bin)
+add_subdirectory(test)
+
diff --git a/SAS/TMSS/services/websocket/bin/CMakeLists.txt b/SAS/TMSS/services/websocket/bin/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9ac088e21eebd153bd547c5b7eec8c569e86abea
--- /dev/null
+++ b/SAS/TMSS/services/websocket/bin/CMakeLists.txt
@@ -0,0 +1,4 @@
+lofar_add_bin_scripts(tmss_websocket_service)
+
+# supervisord config files
+lofar_add_sysconf_files(tmss_websocket_service.ini DESTINATION supervisord.d)
diff --git a/SAS/TMSS/services/websocket/bin/tmss_websocket_service b/SAS/TMSS/services/websocket/bin/tmss_websocket_service
new file mode 100755
index 0000000000000000000000000000000000000000..48f6d5b8aa2893ae04d8a1c6966cb0ceaf3bd797
--- /dev/null
+++ b/SAS/TMSS/services/websocket/bin/tmss_websocket_service
@@ -0,0 +1,24 @@
+#!/usr/bin/python3
+
+# Copyright (C) 2012-2015  ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This file is part of the LOFAR software suite.
+# The LOFAR software suite is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# The LOFAR software suite is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+
+
+from lofar.sas.tmss.services.websocket_service import main
+
+if __name__ == "__main__":
+    main()
diff --git a/SAS/TMSS/services/websocket/bin/tmss_websocket_service.ini b/SAS/TMSS/services/websocket/bin/tmss_websocket_service.ini
new file mode 100644
index 0000000000000000000000000000000000000000..522ffc9076baa05bbf962f14eb52659bfbc63f0b
--- /dev/null
+++ b/SAS/TMSS/services/websocket/bin/tmss_websocket_service.ini
@@ -0,0 +1,9 @@
+[program:tmss_websocket_service]
+command=/bin/bash -c 'source $LOFARROOT/lofarinit.sh;exec tmss_websocket_service'
+user=lofarsys
+stopsignal=INT ; KeyboardInterrupt
+stopasgroup=true ; bash does not propagate signals
+stdout_logfile=%(program_name)s.log
+redirect_stderr=true
+stderr_logfile=NONE
+stdout_logfile_maxbytes=0
diff --git a/SAS/TMSS/services/websocket/lib/CMakeLists.txt b/SAS/TMSS/services/websocket/lib/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..747efb0366e529366a0e5079253bf8c627f0bced
--- /dev/null
+++ b/SAS/TMSS/services/websocket/lib/CMakeLists.txt
@@ -0,0 +1,10 @@
+lofar_find_package(PythonInterp 3.4 REQUIRED)
+include(PythonInstall)
+
+set(_py_files
+    websocket_service.py
+    )
+
+python_install(${_py_files}
+    DESTINATION lofar/sas/tmss/services)
+
diff --git a/SAS/TMSS/services/websocket/lib/websocket_service.py b/SAS/TMSS/services/websocket/lib/websocket_service.py
new file mode 100644
index 0000000000000000000000000000000000000000..188395e82314bae31778c62b4403708ee719b006
--- /dev/null
+++ b/SAS/TMSS/services/websocket/lib/websocket_service.py
@@ -0,0 +1,149 @@
+#!/usr/bin/env python3
+
+# subtask_scheduling.py
+#
+# Copyright (C) 2015
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This file is part of the LOFAR software suite.
+# The LOFAR software suite is free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# The LOFAR software suite is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+
+
+import os
+from optparse import OptionParser, OptionGroup
+import logging
+logger = logging.getLogger(__name__)
+
+from lofar.common import dbcredentials
+from lofar.sas.tmss.client.tmssbuslistener import *
+
+class TMSSEventMessageHandlerForWebsocket(TMSSEventMessageHandler):
+    '''
+    '''
+    def __init__(self) -> None:
+        self._socket = None # TODO: create websocket
+        super().__init__()
+
+    def start_handling(self):
+        #TODO: "open" websocket if needed
+        super().start_handling()
+
+    def stop_handling(self):
+        #TODO: "close" websocket if needed
+        super().stop_handling()
+
+    def _post_update_on_websocket(self, json_blob):
+        #TODO: post the jsob_blob on the socket
+        #TODO: do we want the json_blob as argument, or parameters like: object_type (subtask, task_blueprint, etc) id, action (create/update/delete)
+        #TODO: do we want to post just the id, object_type and action? Or the full object? If the latter, then fetch the object from the database, and post it as json.
+        pass
+
+    def onSubTaskCreated(self, id: int):
+        self._post_update_on_websocket({'id': id, 'object': 'subtask', 'action': 'create'})
+
+    def onSubTaskUpdated(self, id: int):
+        self._post_update_on_websocket({'id': id, 'object': 'subtask', 'action': 'update'})
+
+    def onSubTaskDeleted(self, id: int):
+        self._post_update_on_websocket({'id': id, 'object': 'subtask', 'action': 'delete'})
+
+    def onTaskDraftCreated(self, id: int):
+        #TODO: call _post_update_on_websocket once the method signature is clear
+        pass
+
+    def onTaskDraftUpdated(self, id: int):
+        #TODO: call _post_update_on_websocket once the method signature is clear
+        pass
+
+    def onTaskDraftDeleted(self, id: int):
+        #TODO: call _post_update_on_websocket once the method signature is clear
+        pass
+
+    def onTaskBlueprintCreated(self, id: int):
+        #TODO: call _post_update_on_websocket once the method signature is clear
+        pass
+
+    def onTaskBlueprintUpdated(self, id: int):
+        #TODO: call _post_update_on_websocket once the method signature is clear
+        pass
+
+    def onTaskBlueprintDeleted(self, id: int):
+        #TODO: call _post_update_on_websocket once the method signature is clear
+        pass
+
+    def onSchedulingUnitDraftCreated(self, id: int):
+        #TODO: call _post_update_on_websocket once the method signature is clear
+        pass
+
+    def onSchedulingUnitDraftUpdated(self, id: int):
+        #TODO: call _post_update_on_websocket once the method signature is clear
+        pass
+
+    def onSchedulingUnitDraftDeleted(self, id: int):
+        #TODO: call _post_update_on_websocket once the method signature is clear
+        pass
+
+    def onSchedulingUnitBlueprintCreated(self, id: int):
+        #TODO: call _post_update_on_websocket once the method signature is clear
+        pass
+
+    def onSchedulingUnitBlueprintUpdated(self, id: int):
+        #TODO: call _post_update_on_websocket once the method signature is clear
+        pass
+
+    def onSchedulingUnitBlueprintDeleted(self, id: int):
+        #TODO: call _post_update_on_websocket once the method signature is clear
+        pass
+
+def create_service(exchange: str=DEFAULT_BUSNAME, broker: str=DEFAULT_BROKER):
+    return TMSSBusListener(handler_type=TMSSEventMessageHandlerForWebsocket,
+                           exchange=exchange, broker=broker)
+
+def main():
+    # make sure we run in UTC timezone
+    os.environ['TZ'] = 'UTC'
+
+    logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=logging.INFO)
+
+    # Check the invocation arguments
+    parser = OptionParser('%prog [options]',
+                          description='run the tmss_websocket_service which listens for TMSS event messages on the messagebus, and posts the updates on the websocket for htpp clients.')
+
+    group = OptionGroup(parser, 'Messaging options')
+    group.add_option('-b', '--broker', dest='broker', type='string', default=DEFAULT_BROKER,
+                     help='Address of the message broker, default: %default')
+    group.add_option('-e', "--exchange", dest="exchange", type="string", default=DEFAULT_BUSNAME,
+                     help="exchange where the TMSS event messages are published. [default: %default]")
+    parser.add_option_group(group)
+
+    parser.add_option_group(dbcredentials.options_group(parser))
+    parser.set_defaults(dbcredentials=os.environ.get('TMSS_CLIENT_DBCREDENTIALS', 'TMSS'))
+    (options, args) = parser.parse_args()
+
+    dbcreds = dbcredentials.parse_options(options)
+    logger.info("Using dbcreds: %s" % dbcreds.stringWithHiddenPassword())
+
+    # setup django
+    # TODO: this is only needed if we fetch objects from the database (see above). Otherwise, remove.
+    os.environ["TMSS_DBCREDENTIALS"] = options.dbcredentials
+    os.environ["DJANGO_SETTINGS_MODULE"] = "lofar.sas.tmss.tmss.settings"
+    import django
+    django.setup()
+
+    with create_service(options.exchange, options.broker):
+        waitForInterrupt()
+
+if __name__ == '__main__':
+    main()
diff --git a/SAS/TMSS/services/websocket/test/CMakeLists.txt b/SAS/TMSS/services/websocket/test/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2d2c7976cedf12376f9aaef97e0383c9a805bb5b
--- /dev/null
+++ b/SAS/TMSS/services/websocket/test/CMakeLists.txt
@@ -0,0 +1,7 @@
+# $Id: CMakeLists.txt 32679 2015-10-26 09:31:56Z schaap $
+
+if(BUILD_TESTING)
+    include(LofarCTest)
+
+    lofar_add_test(t_websocket_service)
+endif()
diff --git a/SAS/TMSS/services/websocket/test/t_websocket_service.py b/SAS/TMSS/services/websocket/test/t_websocket_service.py
new file mode 100755
index 0000000000000000000000000000000000000000..faf838939fcb54c1804dc8068c5255cb8bd9a1a9
--- /dev/null
+++ b/SAS/TMSS/services/websocket/test/t_websocket_service.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python3
+
+# Copyright (C) 2012-2015  ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This file is part of the LOFAR software suite.
+# The LOFAR software suite is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# The LOFAR software suite is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+
+import unittest
+import uuid
+
+import logging
+logger = logging.getLogger(__name__)
+logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=logging.INFO)
+
+from lofar.sas.tmss.test.test_utils import TMSSTestEnvironment
+from lofar.sas.tmss.test.tmss_test_data_rest import TMSSRESTTestDataCreator
+
+from lofar.messaging.messagebus import TemporaryExchange, BusListenerJanitor
+from lofar.sas.tmss.services.websocket_service import create_service
+from lofar.common.test_utils import integration_test
+from time import sleep
+from datetime import datetime, timedelta
+
+@integration_test
+class TestSubtaskSchedulingService(unittest.TestCase):
+    '''
+    Tests for the SubtaskSchedulingService
+    '''
+    @classmethod
+    def setUpClass(cls) -> None:
+        cls.TEST_UUID = uuid.uuid1()
+
+        cls.tmp_exchange = TemporaryExchange("%s_%s" % (cls.__name__, cls.TEST_UUID))
+        cls.tmp_exchange.open()
+
+        cls.tmss_test_env = TMSSTestEnvironment(exchange=cls.tmp_exchange.address, populate_test_data=False, populate_schemas=False)
+        cls.tmss_test_env.start()
+
+        cls.test_data_creator = TMSSRESTTestDataCreator(cls.tmss_test_env.django_server.url,
+                                                        (cls.tmss_test_env.ldap_server.dbcreds.user, cls.tmss_test_env.ldap_server.dbcreds.password))
+
+    @classmethod
+    def tearDownClass(cls) -> None:
+        cls.tmss_test_env.stop()
+        cls.tmp_exchange.close()
+
+    def test_01(self):
+        '''
+        This test starts a scheduling service and tmss, creates a chain of subtasks, finishes the first, and checks if the successors are then scheduled.
+        '''
+
+        logger.info(' -- test_01_for_expected_behaviour -- ')
+
+        # create and start the service (the object under test)
+        service = create_service(exchange=self.tmp_exchange.address)
+        with BusListenerJanitor(service):
+            pass
+
+            # TODO: setup http websocket client which connects to our TMSS websocket
+            # TODO: create/update/delete objects like SubTask, TaskBlueprint etc
+            # TODO: check if the correct/expected json_blobs arrive in the websocket client
+
+if __name__ == '__main__':
+    #run the unit tests
+    unittest.main()
diff --git a/SAS/TMSS/services/websocket/test/t_websocket_service.run b/SAS/TMSS/services/websocket/test/t_websocket_service.run
new file mode 100755
index 0000000000000000000000000000000000000000..540c2d5e0571dde79760d2300925db69b70b74dc
--- /dev/null
+++ b/SAS/TMSS/services/websocket/test/t_websocket_service.run
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+# Run the unit test
+source python-coverage.sh
+python_coverage_test "*tmss*" t_websocket_service.py
+
diff --git a/SAS/TMSS/services/websocket/test/t_websocket_service.sh b/SAS/TMSS/services/websocket/test/t_websocket_service.sh
new file mode 100755
index 0000000000000000000000000000000000000000..4e08fcd58615b4c3d3c2cc9971eb891f1c7555e7
--- /dev/null
+++ b/SAS/TMSS/services/websocket/test/t_websocket_service.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+./runctest.sh t_websocket_service
\ No newline at end of file