diff --git a/gstlal-calibration/bin/gstlal_compute_strain b/gstlal-calibration/bin/gstlal_compute_strain
index 5715e6153c1907420d27f2572f875279382970aa..8d97ff30280c3f393df136f57ed5c4f55c778fda 100755
--- a/gstlal-calibration/bin/gstlal_compute_strain
+++ b/gstlal-calibration/bin/gstlal_compute_strain
@@ -72,6 +72,7 @@ from gstlal import pipeparts
 from gstlal import calibration_parts
 from gstlal import simplehandler
 from gstlal import datasource
+from gstlal import calibhandler
 
 from ligo import segments
 
@@ -1095,7 +1096,7 @@ if compute_calib_statevector and (any(line_witness_channel_list) or any(witness_
 
 pipeline = Gst.Pipeline(name="gstlal_compute_strain")
 mainloop = GObject.MainLoop()
-handler = simplehandler.Handler(mainloop, pipeline)
+handler = calibhandler.Handler(mainloop, pipeline)
 
 # 
 # Turn off debugging tools or verboseness
@@ -2422,6 +2423,27 @@ line_sub_bitnum = 26
 noise_sub_bitnum = 27
 noise_sub_gate_bitnum = 28
 
+# We'll only want to check things when the OBSERVATION-INTENT and LOW-NOISE bits are set
+check_state_bitmask = pow(2, obs_intent_bitnum) + pow(2, lownoise_bitnum)
+TDCFs_valid_bitmask_list = []
+if apply_kappatst:
+	TDCFs_valid_bitmask_list.append(pow(2, ktst_smooth_bitnum))
+if apply_kappapum:
+	TDCFs_valid_bitmask_list.append(pow(2, kpum_smooth_bitnum))
+if apply_kappauim:
+	TDCFs_valid_bitmask_list.append(pow(2, kuim_smooth_bitnum))
+if apply_kappac:
+	TDCFs_valid_bitmask_list.append(pow(2, kc_smooth_bitnum))
+if apply_fcc:
+	TDCFs_valid_bitmask_list.append(pow(2, fcc_smooth_bitnum))
+if apply_fs:
+	TDCFs_valid_bitmask_list.append(pow(2, fs_smooth_bitnum))
+if apply_Qinv:
+	TDCFs_valid_bitmask_list.append(pow(2, Qinv_smooth_bitnum))
+TDCFs_valid_bitmask = sum(TDCFs_valid_bitmask_list)
+print(TDCFs_valid_bitmask)
+monitor_bitmask_dict = {'monitor_on': check_state_bitmask, 'TDCFs_valid': TDCFs_valid_bitmask}
+
 if compute_calib_statevector:
 
 	# 
@@ -2960,6 +2982,10 @@ if compute_calib_statevector:
 		calibstatevector = pipeparts.mklatency(pipeline, calibstatevector, name = "%s_calibstatevec" % OutputConfigs["frametype"])
 	dqtagstr = "channel-name=%s:GDS-CALIB_STATE_VECTOR, instrument=%s" % (instrument, instrument)
 	calibstatevector = pipeparts.mktaginject(pipeline, calibstatevector, dqtagstr)
+	calibstatevector = pipeparts.mktee(pipeline, calibstatevector)
+	statevector_monitor = pipeparts.generic(pipeline, calibstatevector, "lal_nxydump")
+	statevector_monitor = pipeparts.mkappsink(pipeline, statevector_monitor, max_buffers = 1)
+	statevector_monitor.connect("new-sample", handler.appsink_statevector_new_buffer, ifo, monitor_bitmask_dict)
 
 #
 # Produce time-dependent correction factors to be recorded in the frames
diff --git a/gstlal-calibration/python/calibhandler.py b/gstlal-calibration/python/calibhandler.py
new file mode 100644
index 0000000000000000000000000000000000000000..dcabcb2c6d389e2b41e148146d06034bb9e20c43
--- /dev/null
+++ b/gstlal-calibration/python/calibhandler.py
@@ -0,0 +1,98 @@
+# Copyright (C) 2019  Maddie Wade, Aaron Viets
+#
+# This program 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 2 of the License, or (at your
+# option) any later version.
+#
+# This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+#
+# =============================================================================
+#
+#                                   Preamble
+#
+# =============================================================================
+#
+
+import numpy
+import StringIO
+import threading
+
+import gi
+gi.require_version('Gst', '1.0')
+from gi.repository import GObject, Gst
+GObject.threads_init()
+Gst.init(None)
+
+from gstlal import simplehandler
+from kafka import KafkaProducer
+
+#
+# =============================================================================
+#
+#                                     Misc
+#
+# =============================================================================
+#
+
+
+		
+
+#
+# =============================================================================
+#
+#                               Pipeline Handler
+#
+# =============================================================================
+#
+
+class Handler(simplehandler.Handler):
+	"""!
+	A subclass of simplehandler.Handler to be used with e.g.,
+ 	gstlal_calibration
+
+	Implements...
+	"""
+	def __init__(self, mainloop, pipeline, kafka_server = None, verbose = False):
+		super(Handler, self).__init__(mainloop, pipeline)
+		#
+		# initialize
+		#
+		self.lock = threading.Lock()
+		self.pipeline = pipeline
+		self.verbose = verbose
+		self.kafka_server = kafka_server
+		if self.kafka_server is not None:
+			self.producer = KafkaProducer(
+					bootstrap_servers = [kafka_server],
+					key_serializer = lambda m: json.dumps(m).encode('utf-8'),
+					value_serializer = lambda m: json.dumps(m).encode('utf-8'),
+				)
+
+	def appsink_statevector_new_buffer(self, elem, ifo, bitmaskdict):
+		with self.lock:
+			# retrieve data from appsink buffer
+			buf = elem.emit("pull-sample").get_buffer()
+			result, mapinfo = buf.map(Gst.MapFlags.READ)
+			buf_timestamp = LIGOTimeGPS(0, buf.pts)
+			if mapinfo.data:
+				s = StringIO.StringIO(mapinfo.data)
+				time, state = s.getvalue().split('\n')[0].split()
+				state = int(state)
+			buf.unmap(mapinfo)
+			monitor_dict = {}
+			for keys, bitmask in bitmaskdict.items():
+				monitor_dict[key] = state & bitmask
+			if self.kafka_server is not None:
+				self.producer.send("%s_statevector_bit_check" % ifo, value = monitor_dict) 
+
+				
+