private void DeviceUpdatedCallback(object sender, EventArgs e) { MqttDevice device = (MqttDevice)sender; foreach (DataFileTemplate template in templates) { if (device.Key == template.UniqueID || device.Name == template.UniqueID) { device.WriteFile(template); } } OnDeviceUpdate(this, device); }
private void IngestMessage(MqttApplicationMessage m) { try { int idxDevices = m.Topic.IndexOf("/devices/"); if (idxDevices < 0) { OnError(this, "Topic \"" + m.Topic + "\" did not match the expected pattern."); return; } string subtopic = m.Topic.Substring(idxDevices + "/devices/".Length); int idxLastSlash = subtopic.LastIndexOf('/'); if (idxLastSlash < 0) { OnError(this, "Topic \"" + m.Topic + "\" did not match the expected pattern."); return; } string fieldName = subtopic.Substring(idxLastSlash + 1); if (fieldName == "sequence_num" || fieldName == "message_type" || fieldName == "mic") { return; } string deviceKey = StringUtil.MakeSafeForFileName(subtopic.Substring(0, idxLastSlash), "_").Replace('=', '_').Replace('[', '_').Replace(']', '_'); MqttDevice device = devices.GetOrAdd(deviceKey, s => { MqttDevice o = new MqttDevice(); o.Key = deviceKey; o.OnUpdate += DeviceUpdatedCallback; o.OnBackgroundError += DeviceErrorCallback; return(o); }); bool changed = false; string newValue = ByteUtil.Utf8NoBOM.GetString(m.Payload); device.SetValue(fieldName, newValue, ref changed); } catch (Exception ex) { OnError(this, ex.ToString()); } }
public override void handleGETRequest(HttpProcessor p) { if (HandleRequestFromAcuriteAccessDevice(p)) { return; } else if (p.requestedPage == "json") { IEnumerable <object> sensors = BuildSensorList(p); string str = JsonConvert.SerializeObject(sensors); p.writeSuccess("application/json", HttpProcessor.Utf8NoBOM.GetByteCount(str), additionalHeaders: getAdditionalHeaders(), keepAlive: p.keepAliveRequested); p.outputStream.Write(str); } else if (p.requestedPage == "params") { StringBuilder sb = new StringBuilder(); IEnumerable <object> sensors = BuildSensorList(p); foreach (object o in sensors) { if (o is SensorBase) { SensorBase sensor = (SensorBase)o; sb.Append("[" + sensor.UniqueID + "]<br>"); sb.Append(sensor.GetParams()); sb.Append("<br><br>"); } else { MqttDevice d = (MqttDevice)o; sb.Append("[" + d.OrderBy + "]<br>"); sb.Append(d.GetParams()); sb.Append("<br><br>"); } } string str = sb.ToString(); p.writeSuccess(contentLength: HttpProcessor.Utf8NoBOM.GetByteCount(str), additionalHeaders: getAdditionalHeaders(), keepAlive: p.keepAliveRequested); p.outputStream.Write(str); } else if (p.requestedPage == "lastacuriteaccessrequests") { string str = "[\r\n" + string.Join("]\r\n\r\n***************************\r\n\r\n[\r\n", lastAcuriteAccessRequests.Select(i => i.ToString())) + "\r\n]\r\n"; p.writeSuccess("text/plain", HttpProcessor.Utf8NoBOM.GetByteCount(str), additionalHeaders: getAdditionalHeaders(), keepAlive: p.keepAliveRequested); p.outputStream.Write(str); } else if (p.requestedPage == "getfriendlydevicenames") { string str = JsonConvert.SerializeObject(Program.settings.GetFriendlyDeviceNames(), Formatting.Indented); p.writeSuccess("application/json", HttpProcessor.Utf8NoBOM.GetByteCount(str), additionalHeaders: getAdditionalHeaders(), keepAlive: p.keepAliveRequested); p.outputStream.Write(str); } else if (p.requestedPage == "setfriendlydevicename") { string key = p.GetParam("key"); string value = p.GetParam("value"); if (!Program.settings.TrySetFriendlyDeviceName(key, value, out string errorMessage)) { p.writeSuccess("text/plain", HttpProcessor.Utf8NoBOM.GetByteCount(errorMessage), responseCode: "400 Bad Request", additionalHeaders: getAdditionalHeaders(), keepAlive: p.keepAliveRequested); p.outputStream.Write(errorMessage); } else { p.writeSuccess("text/plain", 0, additionalHeaders: getAdditionalHeaders(), keepAlive: p.keepAliveRequested); } } else { List <DataFileTemplate> templates = Program.settings.GetSensorDataTemplates(); string pageLower = p.requestedPage.ToLower(); foreach (DataFileTemplate template in templates) { if (template.FileName.ToLower() == pageLower) { FileInfo fi = new FileInfo("SensorData/" + template.FileName); if (fi.Exists) { p.writeSuccess("text/plain; charset=UTF-8", fi.Length, additionalHeaders: getAdditionalHeaders(), keepAlive: p.keepAliveRequested); p.outputStream.Write(File.ReadAllText(fi.FullName, Encoding.GetEncoding(1252))); } else { p.writeFailure(); } return; } } IEnumerable <object> sensors = BuildSensorList(p); StringBuilder sb = new StringBuilder(); sb.AppendLine(@"<!DOCTYPE html> <html> <head> <title>AcuRite Sniffer Home</title> </head> <body> <h2>The following commands are available:</h2> <p><a href=""/json"">/json</a> - Get JSON records for all sensors</p> <div></div>" ); foreach (object sensor in sensors) { string key = OrderSelector(sensor); sb.AppendLine(); sb.AppendLine("\t<div><a href=\"/json?uniqueid=" + StringUtil.HtmlAttributeEncode(Uri.EscapeDataString(key)) + "\">/json?uniqueid=" + StringUtil.HtmlEncode(Uri.EscapeDataString(key)) + "</a> - Get JSON record for the sensor \"" + StringUtil.HtmlEncode(key) + "\"</div>"); } sb.AppendLine("<p></p>"); sb.AppendLine("<p>Add multiple uniqueid arguments to retrieve values from multiple sensors.</p>"); sb.AppendLine("<p></p>"); sb.AppendLine(@"<p><a href=""/params"">/params</a> - Get a list of parameters available for all sensors</p>"); sb.AppendLine("<p></p>"); foreach (object sensor in sensors) { string key = OrderSelector(sensor); sb.AppendLine(); sb.AppendLine("\t<div><a href=\"/params?uniqueid=" + StringUtil.HtmlAttributeEncode(Uri.EscapeDataString(key)) + "\">/params?uniqueid=" + StringUtil.HtmlEncode(Uri.EscapeDataString(key)) + "</a> - Get a list of parameters available for sensor \"" + StringUtil.HtmlEncode(key) + "\"</div>"); } sb.AppendLine("<p></p>"); foreach (DataFileTemplate template in templates.OrderBy(t => t.FileName)) { sb.AppendLine(); sb.AppendLine("\t<div><a href=\"/" + template.FileName + "\">/" + template.FileName + "</a> - Get a custom text file for the sensor \"" + template.UniqueID + "\"</div>"); } sb.AppendLine(@"<p><a href=""/lastacuriteaccessrequests"">/lastacuriteaccessrequests</a> - Get the last 10 requests captured and proxied from configured AcuRite Access IP Addresses.</p>"); sb.AppendLine("<p></p>"); sb.AppendLine(@"<p><a href=""/getfriendlydevicenames"">/getfriendlydevicenames</a> - Get a list of key/value pairs mapping unique device IDs to unique friendly names. Friendly names can be used as an alternative to the device ID when querying device data and writing custom text file definitions.</p>"); sb.AppendLine(@"<p><a href=""/setfriendlydevicename?key=XXX&value=XXX"">/setfriendlydevicename?key=XXX&value=XXX</a> - Set a mapping for device ID to unique friendly name.</p>"); sb.AppendLine("<p></p>"); sb.AppendLine("<p>Set Friendly Names:</p>"); int id = 0; foreach (object sensor in sensors) { string key = GetDeviceKey(sensor); sb.AppendLine(); string friendlyName; Program.settings.TryGetFriendlyDeviceName(key, out friendlyName); sb.Append("\t<div><span style=\"font-family: consolas, monospace;\">"); sb.Append(StringUtil.HtmlEncode(key)); sb.AppendLine(":</span>"); sb.AppendLine("<input type=\"text\" id=\"friendlyName" + id + "\" value=\"" + StringUtil.HtmlAttributeEncode(friendlyName) + "\">"); sb.AppendLine("<input type=\"button\" value=\"<- Set\" onclick=\"setDeviceFriendlyName(event, '" + StringUtil.HtmlAttributeEncode(key) + "', 'friendlyName" + id + "')\">"); sb.AppendLine("</div>"); id++; } sb.Append(@" <script type=""text/javascript""> function setDeviceFriendlyName(e, key, inputId) { try { e.target.setAttribute('disabled', 'disabled'); var value = document.getElementById(inputId).value; fetch('/setfriendlydevicename?key=' + encodeURIComponent(key) + '&value=' + encodeURIComponent(value)) .then(function (result) { e.target.removeAttribute('disabled'); }) .catch(function (err) { alert(err); }); } catch(ex) { alert(ex.message); } } </script> </body> </html>"); string str = sb.ToString(); p.writeSuccess(contentLength: HttpProcessor.Utf8NoBOM.GetByteCount(str), additionalHeaders: getAdditionalHeaders(), keepAlive: p.keepAliveRequested); p.outputStream.Write(str); } }