diff --git a/components/common/cpp/include/ftl/configurable.hpp b/components/common/cpp/include/ftl/configurable.hpp
index 210184e76e50ab6f9c6ed7fe3f6c6afea7cfee29..3fb497c1d3bb9ccc17d543db5716670ca79c55f6 100644
--- a/components/common/cpp/include/ftl/configurable.hpp
+++ b/components/common/cpp/include/ftl/configurable.hpp
@@ -97,7 +97,7 @@ class Configurable {
 	void on(const std::string &prop, std::function<void(const config::Event&)>);
 
 	protected:
-	nlohmann::json config_;
+	nlohmann::json &config_;
 
 	private:
 	std::map<std::string, std::list<std::function<void(const config::Event&)>>> observers_; 
@@ -132,7 +132,7 @@ std::optional<T> ftl::Configurable::get(const std::string &name) {
 		std::string res_uri = config_["$ref"].get<std::string>()+"/"+name;
 		auto &r = ftl::config::resolve(res_uri);
 
-		DLOG(1) << "GET: " << res_uri << " = " << r;
+		DLOG(2) << "GET: " << res_uri << " = " << r;
 
 		try {
 			return r.get<T>();
diff --git a/components/common/cpp/include/ftl/configuration.hpp b/components/common/cpp/include/ftl/configuration.hpp
index 4d3d9134a10ad9fc9628dd23b67afd2a90ac65fe..099a6c33b504dfb97ec9f0b9f3ff2ffd09236ad5 100644
--- a/components/common/cpp/include/ftl/configuration.hpp
+++ b/components/common/cpp/include/ftl/configuration.hpp
@@ -27,6 +27,12 @@ std::optional<std::string> locateFile(const std::string &name);
 
 Configurable *configure(int argc, char **argv, const std::string &root);
 
+/**
+ * Change a configuration value based upon a URI. Return true if changed,
+ * false if it was not able to change.
+ */
+bool update(const std::string &puri, const json_t &value);
+
 /**
  * Resolve a JSON schema reference, but do not wait for a remote reference
  * if it is not available. A null entity is returned if not resolved.
diff --git a/components/common/cpp/src/configuration.cpp b/components/common/cpp/src/configuration.cpp
index f21eb026202dd2cfaaa1ed822932414136849cdb..58cade5dd1d08c1e9b9c7e87ecf56da327465679 100644
--- a/components/common/cpp/src/configuration.cpp
+++ b/components/common/cpp/src/configuration.cpp
@@ -192,6 +192,43 @@ void ftl::config::registerConfigurable(ftl::Configurable *cfg) {
 
 json_t null_json;
 
+bool ftl::config::update(const std::string &puri, const json_t &value) {
+	// Remove last component of URI
+	string tail = "";
+	string head = "";
+	size_t last_hash = puri.find_last_of('#');
+	if (last_hash != string::npos) {
+		size_t last = puri.find_last_of('/');
+		if (last != string::npos && last > last_hash) {
+			tail = puri.substr(last+1);
+			head = puri.substr(0, last);
+		} else {
+			tail = puri.substr(last_hash+1);
+			head = puri.substr(0, last_hash);
+		}
+	} else {
+		LOG(WARNING) << "Expected a # in an update URI: " << puri;
+		return false;
+	}
+
+	Configurable *cfg = find(head);
+
+	if (cfg) {
+		DLOG(1) << "Updating CFG: " << head << "[" << tail << "] = " << value;
+		cfg->set<json_t>(tail, value);
+	} else {
+		DLOG(1) << "Updating: " << head << "[" << tail << "] = " << value;
+		auto r = resolve(head);
+		if (!r.is_structured()) {
+			LOG(ERROR) << "Cannot update property '" << tail << "' of '" << head << "'";
+			return false;
+		}
+
+		r[tail] = value;
+		return true;
+	}
+}
+
 json_t &ftl::config::resolve(const std::string &puri) {
 	string uri_str = puri;
 
@@ -219,44 +256,6 @@ json_t &ftl::config::resolve(const std::string &puri) {
 		} catch(...) {
 			return null_json;
 		}
-	//}
-/*
-
-		int n = 0;
-		while (u.size() != 0) {
-			LOG(INFO) << "Resolve URI: " << u;
-			auto ix = config_index.find(u);
-			if (ix == config_index.end()) {
-				u = uri.getBaseURI(--n);
-				continue;
-			}
-			//LOG(INFO) << "FOUND URI " << *(*ix).second;
-
-			if (n == 0) {
-				return *(*ix).second;
-			} else {
-				// Must apply path segments again...
-				nlohmann::json *c = (*ix).second;
-				while (n < 0) {
-					auto seg = uri.getPathSegment(n++);
-					c = &(*c)[seg];
-					
-					// Recursive resolve...
-					if ((*c).is_string()) {
-						c = &resolve(*c);
-					}
-				}
-
-				// Give it the correct URI
-				if (!(*c)["$id"].is_string()) {
-					(*c)["$id"] = uri.getBaseURI();
-				}
-
-				return *c;
-			}
-		}
-		LOG(FATAL) << "Unresolvable configuration URI: " << uri.getBaseURI();
-		return null_json;*/
 	} else {
 		return null_json;
 	}
@@ -364,7 +363,7 @@ static void process_options(Configurable *root, const map<string, string> &opts)
 		}
 
 		try {
-			//auto ptr = nlohmann::json::json_pointer("/"+opt.first);
+			/* //auto ptr = nlohmann::json::json_pointer("/"+opt.first);
 			auto ptr = ftl::config::resolve(*root->get<string>("$id") + string("/") + opt.first);
 
 			LOG(INFO) << "PARAM RES TO " << (*root->get<string>("$id") + string("/") + opt.first);
@@ -375,7 +374,10 @@ static void process_options(Configurable *root, const map<string, string> &opts)
 				LOG(ERROR) << "Incorrect type for argument " << opt.first << " - expected '" << type << "', got '" << v.type_name() << "'";
 				continue;
 			}
-			ptr.update(v);
+			ptr.swap(v);*/
+
+			auto v = nlohmann::json::parse(opt.second);
+			ftl::config::update(*root->get<string>("$id") + string("/") + opt.first, v);
 		} catch(...) {
 			LOG(ERROR) << "Unrecognised option: " << *root->get<string>("$id") << "#" << opt.first;
 		}
diff --git a/components/rgbd-sources/src/rgbd_streamer.cpp b/components/rgbd-sources/src/rgbd_streamer.cpp
index 8cf1e8f96c919aef4c5eb8e118e11272aeab70b5..375ae8ebd0d697b6bdab345292e25e9a419bb86d 100644
--- a/components/rgbd-sources/src/rgbd_streamer.cpp
+++ b/components/rgbd-sources/src/rgbd_streamer.cpp
@@ -161,7 +161,7 @@ void Streamer::_schedule() {
 
 		shared_lock<shared_mutex> slk(s.second->mutex);
 		if (s.second->state != 0) {
-			LOG(ERROR) << "Stream not ready to schedule on time: " << uri;
+			LOG(WARNING) << "Stream not ready to schedule on time: " << uri;
 			continue;
 		}
 		if (s.second->clients[0].size() == 0) {