diff --git a/.gitattributes b/.gitattributes
index 095be245ab0851640ac286ca379eaa938e5294dd..2ca68313e2b2de80121a1af13a74047ba29fe8a3 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -4832,6 +4832,9 @@ SAS/OTDB_Services/test/CMakeLists.txt -text
 SAS/OTDB_Services/test/t_TreeService.py -text
 SAS/OTDB_Services/test/t_TreeService.run -text svneol=unset#application/x-shellscript
 SAS/OTDB_Services/test/t_TreeService.sh -text svneol=unset#application/x-shellscript
+SAS/OTDB_Services/test/t_TreeStatusEvents.py -text
+SAS/OTDB_Services/test/t_TreeStatusEvents.run -text svneol=unset#application/x-shellscript
+SAS/OTDB_Services/test/t_TreeStatusEvents.sh -text svneol=unset#application/x-shellscript
 SAS/OTDB_Services/test/unittest_db.dump.gz -text svneol=unset#application/x-gzip
 SAS/Scheduler/src/.default_settings.set -text
 SAS/Scheduler/src/LOFAR_libScheduler.pro -text
diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc
index 9a81480094e613fa4e1318cce2aa003475d01a4f..268a664f815bdd046c72c783ba3a28f8f5019560 100644
--- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc
+++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc
@@ -99,6 +99,14 @@ MACScheduler::MACScheduler() :
 	itsFinishedPeriod= globalParameterSet()->getTime("finishedPeriod", 86400) / 60; // in minutes
 	itsMaxPlanned    = globalParameterSet()->getTime("maxPlannedList",  30);
 	itsMaxFinished   = globalParameterSet()->getTime("maxFinishedList", 40);
+    itsExclPLcluster = globalParameterSet()->getString("excludePipelinesOnThisCluster", "");
+    if (itsExclPLcluster.length() > 0) {
+        LOG_INFO_STR("NOT running the pipelines on cluster: " << itsExclPLcluster);
+    	// We need to exclude this cluster for pipelines so make sure the name begins with the 'not'-sign.
+        if (itsExclPLcluster[0] != '!') {
+            itsExclPLcluster.insert(0, 1, '!');
+		}
+	}
 
 	ASSERTSTR(itsMaxPlanned + itsMaxFinished < MAX_CONCURRENT_OBSERVATIONS, 
 				"maxPlannedList + maxFinishedList should be less than " << MAX_CONCURRENT_OBSERVATIONS);
@@ -623,8 +631,8 @@ void MACScheduler::_updatePlannedList()
 	ptime	currentTime = from_time_t(now);
 	ASSERTSTR (currentTime != not_a_date_time, "Can't determine systemtime, bailing out");
 
-	// get new list (list is ordered on starttime)
-	vector<OTDBtree> plannedDBlist = itsOTDBconnection->getTreeGroup(1, itsPlannedPeriod);	// planned observations
+	// get new list (list is ordered on starttime) of planned observations
+	vector<OTDBtree> plannedDBlist = itsOTDBconnection->getTreeGroup(1, itsPlannedPeriod, itsExclPLcluster);	
 
 	if (!plannedDBlist.empty()) {
 		LOG_DEBUG(formatString("OTDBCheck:First planned observation (%d) is at %s (active over %d seconds)", 
@@ -754,7 +762,7 @@ void MACScheduler::_updateActiveList()
 	LOG_DEBUG("_updateActiveList()");
 
 	// get new list (list is ordered on starttime)
-	vector<OTDBtree> activeDBlist = itsOTDBconnection->getTreeGroup(2, 0);
+	vector<OTDBtree> activeDBlist = itsOTDBconnection->getTreeGroup(2, 0, itsExclPLcluster);
 	if (activeDBlist.empty()) {
 		LOG_DEBUG ("No active Observations");
 		// NOTE: do not exit routine on emptylist: we need to write an empty list to clear the DB
@@ -797,7 +805,7 @@ void MACScheduler::_updateFinishedList()
 	LOG_DEBUG("_updateFinishedList()");
 
 	// get new list (list is ordered on starttime)
-	vector<OTDBtree> finishedDBlist = itsOTDBconnection->getTreeGroup(3, itsFinishedPeriod);
+	vector<OTDBtree> finishedDBlist = itsOTDBconnection->getTreeGroup(3, itsFinishedPeriod, itsExclPLcluster);
 	if (finishedDBlist.empty()) {
 		LOG_DEBUG ("No finished Observations");
 		// NOTE: do not exit routine on emptylist: we need to write an empty list to clear the DB
diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.conf.in b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.conf.in
index 911f75463162324556fcb8d03141d9aece3381b6..ed9c486a187ff5e142c65ff6fd5a39ac561f72e8 100644
--- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.conf.in
+++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.conf.in
@@ -30,3 +30,7 @@ maxFinishedList	= 40	# Never show more finished observations
 #ChildControl.MaxStartupRetry	   = 5
 
 ParsetQueuename = lofar.task.specification.system
+
+# Pipelines on cluster X can be ignored by the MACScheduler with this key.
+# use e.g. 'CEP2' or 'CEP4'
+excludePipelinesOnThisCluster = ''
diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h
index 5654ea1434ea58adf785ddd095daf398e81aac09..188d01364883ed3649aa4a234e3233eda771c34c 100644
--- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h
+++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h
@@ -168,6 +168,9 @@ private:
 	// OTDB related variables.
    	OTDB::OTDBconnection*	itsOTDBconnection;	// connection to the database
 
+	// Cluster to exclude for pipelines. Key is used in the getTreeGroup stored-procedure in OTDB.
+	string				itsExclPLcluster;		// like !CEP2 or !CEP4
+
 	// Messagebus related variables
 	ToBus*					itsMsgQueue;		// Bus used for sending
 };
diff --git a/MAC/APL/MainCU/src/MACScheduler/MACSchedulerMain.cc b/MAC/APL/MainCU/src/MACScheduler/MACSchedulerMain.cc
index 79ede7d94fe484fececff88c7e8db6692cf2d601..6d8caa91d240823ee307ba586b453bf28ae0091a 100644
--- a/MAC/APL/MainCU/src/MACScheduler/MACSchedulerMain.cc
+++ b/MAC/APL/MainCU/src/MACScheduler/MACSchedulerMain.cc
@@ -39,7 +39,7 @@ int main(int argc, char* argv[])
 {
 	GCFScheduler::instance()->init(argc, argv, "MACScheduler");
 
-  MessageBus::init();
+    MessageBus::init();
 
 	ChildControl*	cc = ChildControl::instance();
 	cc->start();	// make initial transition
diff --git a/SAS/OTDB_Services/TreeStatusEvents.py b/SAS/OTDB_Services/TreeStatusEvents.py
index 918cc3e4803538e00f15354fd99ecf54f7e87763..2362825ed0ca7398462ea553fa636e87a9fcbb50 100755
--- a/SAS/OTDB_Services/TreeStatusEvents.py
+++ b/SAS/OTDB_Services/TreeStatusEvents.py
@@ -137,7 +137,7 @@ if __name__ == "__main__":
                 else:
                     for (treeid, state, modtime, creation) in record_list:
                         content = { "treeID" : treeid, "state" : state, "time_of_change" : modtime }
-                        msg = EventMessage("otdb.treestatus", content)
+                        msg = EventMessage(context="otdb.treestatus", content=content)
                         print treeid, state, modtime, creation
                         send_bus.send(msg)
                         open('time_save.txt', 'wb').write(creation)
diff --git a/SAS/OTDB_Services/test/CMakeLists.txt b/SAS/OTDB_Services/test/CMakeLists.txt
index edf67b38ccac54ec38b9061da1ae04c1cff3a2bc..f5796145f0c26c0dfdf4d61b0b7efa3ab4f7f524 100644
--- a/SAS/OTDB_Services/test/CMakeLists.txt
+++ b/SAS/OTDB_Services/test/CMakeLists.txt
@@ -3,4 +3,5 @@
 include(LofarCTest)
 
 lofar_add_test(t_TreeService)
+lofar_add_test(t_TreeStatusEvents)
 
diff --git a/SAS/OTDB_Services/test/t_TreeService.run b/SAS/OTDB_Services/test/t_TreeService.run
index 37a63124c93466758d77378bdd874591bcef92a4..14cc7a3968eb5a1f300a595e24721b6109db21a5 100755
--- a/SAS/OTDB_Services/test/t_TreeService.run
+++ b/SAS/OTDB_Services/test/t_TreeService.run
@@ -1,4 +1,4 @@
-#!/bin/sh -ex
+#!/bin/sh -x
 # constants
 DBHOST=sas099.control.lofar
 
diff --git a/SAS/OTDB_Services/test/t_TreeStatusEvents.py b/SAS/OTDB_Services/test/t_TreeStatusEvents.py
new file mode 100644
index 0000000000000000000000000000000000000000..b1acc0634a92c8ff9d28e2fa452c725b9c8b1096
--- /dev/null
+++ b/SAS/OTDB_Services/test/t_TreeStatusEvents.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python
+#coding: iso-8859-15
+#
+# 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/>.
+#
+# $Id: Backtrace.cc 31468 2015-04-13 23:26:52Z amesfoort $
+"""
+RPC functions that allow access to (VIC) trees in OTDB.
+
+TaskSpecificationRequest: get the specification(parset) of a tree as dict.
+KeyUpdateCommand        : function to update the value of multiple (existing) keys.
+StatusUpdateCommand     : finction to update the status of a tree.
+"""
+
+import sys, pg
+import logging
+from optparse import OptionParser
+from lofar.messaging import FromBus
+
+logging.basicConfig(stream=sys.stdout, level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+if __name__ == "__main__":
+    # Check the invocation arguments
+    parser = OptionParser("%prog [options]")
+    parser.add_option("-D", "--database", dest="dbName", type="string", default="",
+                      help="Name of the database")
+    parser.add_option("-H", "--hostname", dest="dbHost", type="string", default="sasdb",
+                      help="Hostname of database server")
+    parser.add_option("-B", "--busname", dest="busname", type="string", default="", 
+                      help="Busname or queue-name the status changes are published on")
+    (options, args) = parser.parse_args()
+    
+    if not options.dbName:
+        print "Missing database name"
+        parser.print_help()
+        sys.exit(1)
+    
+    if not options.dbHost:
+        print "Missing database server name"
+        parser.print_help()
+        sys.exit(1)
+    
+    if not options.busname:
+        print "Missing busname"
+        parser.print_help()
+        sys.exit(1)
+
+    try:
+        print "user=postgres, host=", options.dbHost, "dbname=", options.dbName
+        otdb_connection = pg.connect(user="postgres", host=options.dbHost, dbname=options.dbName)
+    except (TypeError, SyntaxError, pg.InternalError):
+        print "DatabaseError: Connection to database could not be made"
+        sys.exit(77)
+
+    with FromBus(options.busname) as frombus:
+        # First drain the queue
+        no_exception = True
+        while no_exception:
+            try:
+                msg = frombus.receive(timeout=1)
+                frombus.ack(msg)
+            except Exception:
+                no_exception = False
+
+        otdb_connection.query("select setTreeState(1, %d, %d::INT2,'%s')" % (1099266, 500, False))
+        msg = frombus.receive(timeout=5)	  # TreeStateEVent are send every 2 seconds
+        frombus.ack(msg)
+        msg.show()
+        try:
+            ok = (msg.content['treeID'] == 1099266 and msg.content['state'] == 500)
+        except IndexError:
+            ok = False
+
+    sys.exit(not(ok))   # 0 = success
diff --git a/SAS/OTDB_Services/test/t_TreeStatusEvents.run b/SAS/OTDB_Services/test/t_TreeStatusEvents.run
new file mode 100755
index 0000000000000000000000000000000000000000..22148b99324eeabc1c49ec8f3b56edb082a8df64
--- /dev/null
+++ b/SAS/OTDB_Services/test/t_TreeStatusEvents.run
@@ -0,0 +1,49 @@
+#!/bin/sh -x
+# constants
+DBHOST=sas099.control.lofar
+
+#cleanup on normal exit and on SIGHUP, SIGINT, SIGQUIT, and SIGTERM
+trap 'qpid-config del exchange --force $queue ; kill ${SERVICE_PID}' 0 1 2 3 15
+
+# Generate randome queue name
+queue=$(< /dev/urandom tr -dc [:alnum:] | head -c16)
+
+# Create the queue
+qpid-config add exchange topic $queue
+
+# Setup a clean database with predefined content
+dropdb -U postgres -h ${DBHOST} unittest_db
+gzip -dc $srcdir/unittest_db.dump.gz | psql -U postgres -h ${DBHOST} -f -
+TreeStatusEvents.py -B $queue -D unittest_db -H ${DBHOST} &
+SERVICE_PID=$!
+# Starting up takes a while
+sleep 3
+
+# Run the unit test
+# either with or without code coverage measurements,
+# depending wheter coverage has been installed
+
+if type "coverage" > /dev/null; then
+    #run test using python coverage tool
+
+    #erase previous results
+    coverage erase
+
+    #setup coverage config file
+    printf "[report]\nexclude_lines = \n  if __name__ == .__main__.\n  def main\n" > .coveragerc
+
+    coverage run --branch --include=*Messaging/python* t_TreeStatusEvents.py -D unittest_db -H ${DBHOST} -B $queue
+    RESULT=$?
+    if [ $RESULT -eq 0 ]; then
+        echo " *** Code coverage results *** "
+        coverage report -m
+        echo " *** End coverage results *** "
+    fi
+    exit $RESULT
+else
+    #coverage not available
+    echo "Please run: 'pip install coverage' to enable code coverage reporting of the unit tests"
+    #run plain test script
+    python t_TreeStatusEvents.py -D unittest_db -H ${DBHOST} -B $queue 
+fi
+
diff --git a/SAS/OTDB_Services/test/t_TreeStatusEvents.sh b/SAS/OTDB_Services/test/t_TreeStatusEvents.sh
new file mode 100755
index 0000000000000000000000000000000000000000..63d2326f4d9a556cfd978b626fa5429f6a8bd597
--- /dev/null
+++ b/SAS/OTDB_Services/test/t_TreeStatusEvents.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+./runctest.sh t_TreeStatusEvents
diff --git a/SAS/OTDB_Services/test/unittest_db.dump.gz b/SAS/OTDB_Services/test/unittest_db.dump.gz
index b0320fb84f5f3d3ab2febf76c4fe591c7d92397f..145e5613516d3e0018a1e15fbe82124d27d98832 100644
Binary files a/SAS/OTDB_Services/test/unittest_db.dump.gz and b/SAS/OTDB_Services/test/unittest_db.dump.gz differ