private static List<WemosMessage> ParseBuffer() { List<WemosMessage> result = new List<WemosMessage>(); string pattern = @"(?<v0>[\s\S]*);(?<v1>[\s\S]*);(?<v2>[\s\S]*);(?<v3>[\s\S]*);(?<v4>[\s\S]*)\n"; Regex r = new Regex(pattern, RegexOptions.IgnoreCase); MatchCollection entries = r.Matches(buffer); if (entries.Count > 0) { buffer = r.Replace(buffer, ""); foreach (Match entry in entries) { WemosMessage msg = null; try { msg = new WemosMessage( int.Parse(entry.Groups["v0"].Value), int.Parse(entry.Groups["v1"].Value), (WemosMessageType) int.Parse(entry.Groups["v2"].Value), int.Parse(entry.Groups["v3"].Value)) .Set(entry.Groups["v4"].Value.Trim()); } catch (Exception) { } if (msg != null) result.Add(msg); } } return result; }
public async Task Send(WemosMessage msg) { if (msg != null) { var str = msg.ToDto(); if (!string.IsNullOrEmpty(str)) { try { // GetOutputStreamAsync can be called multiple times on a single DatagramSocket instance to obtain // IOutputStreams pointing to various different remote endpoints. The remote hostname given to // GetOutputStreamAsync can be a unicast, multicast or broadcast address. IOutputStream outputStream = await listenerSocket.GetOutputStreamAsync(new HostName(remoteMulticastAddress), remoteService); DataWriter writer = new DataWriter(outputStream); writer.WriteString(str); await writer.StoreAsync(); } catch (Exception exception) { // If this is an unknown status it means that the error is fatal and retry will likely fail. if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) throw; //rootPage.NotifyUser("Send failed with error: " + exception.Message, NotifyType.ErrorMessage); } } } }
public WemosMessageEventArgs(WemosMessage message) { Message = message; }
public override bool IsMyMessage(WemosMessage message) { return WemosPlugin.IsMessageFromLine(message, LineSwitch); }
public async Task Send(WemosMessage data) { await transport.Send(data); }
private void NotifyMessageReceivedForPlugins(WemosMessage msg) { Run(WemosMessageHandlers, x => x(msg)); }
private async Task ProcessMessage(WemosMessage message, HostName remoteAddress) { WemosNode node = GetNode(message.NodeID); WemosLine line = GetLine(message.NodeID, message.LineID); switch (message.Type) { #region Presentation case WemosMessageType.Presentation: // sent by a nodes when they present attached sensors. if (message.LineID == -1) // node { if (node == null) { node = new WemosNode { NodeID = message.NodeID, Type = (WemosLineType) message.SubType, ProtocolVersion = message.GetFloat(), IPAddress = remoteAddress.CanonicalName }; Save(node); } else { node.Type = (WemosLineType) message.SubType; node.ProtocolVersion = message.GetFloat(); node.IPAddress = remoteAddress.CanonicalName; SaveOrUpdate(node); } //NotifyMessageReceivedForPlugins(message); //NotifyMessageReceivedForScripts(message); //NotifyForSignalR(new { MsgId = "NodePresentation", Data = BuildNodeRichWebModel(node) }); } else // line { if (node != null) { if (line == null) { line = new WemosLine() { NodeID = node.NodeID, LineID = message.LineID, Type = (WemosLineType) message.SubType, ProtocolVersion = message.GetFloat() }; Save(line); } else { line.Type = (WemosLineType) message.SubType; line.ProtocolVersion = message.GetFloat(); SaveOrUpdate(line); } //NotifyMessageReceivedForPlugins(message); //NotifyMessageReceivedForScripts(message); //NotifyForSignalR(new { MsgId = "SensorPresentation", Data = BuildSensorRichWebModel(line) }); } } break; #endregion #region Report case WemosMessageType.Report: if (line != null) { //NotifyMessageCalibrationForPlugins(message); // before saving to DB plugins may adjust the sensor value due to their calibration params foreach (var controller in controllers) if (controller.IsMyMessage(message)) { controller.MessageCalibration(message); break; } WemosLineValue sv = new WemosLineValue() { NodeID = message.NodeID, LineID = message.LineID, TimeStamp = DateTime.UtcNow, Type = (WemosLineType) message.SubType, Value = message.GetFloat() }; Save(sv); line.LastTimeStamp = sv.TimeStamp; line.LastValue = sv.Value; SaveOrUpdate(line); //NotifyForSignalR(new { MsgId = "MySensorsTileContent", Data = BuildTileContent() }); // update MySensors tile NotifyMessageReceivedForPlugins(message); //NotifyMessageReceivedForScripts(message); //NotifyForSignalR(new { MsgId = "SensorValue", Data = sv }); // notify Web UI foreach (var controller in controllers) if (controller.IsMyMessage(message)) controller.MessageReceived(message); } break; #endregion #region Set case WemosMessageType.Set: // sent to a sensor when a sensor value should be updated break; #endregion #region Request case WemosMessageType.Get: // requests a variable value (usually from an actuator destined for controller) break; #endregion #region Internal case WemosMessageType.Internal: var imt = (WemosInternalMessageType) message.SubType; switch (imt) { case WemosInternalMessageType.BatteryLevel: // int, in % if (node != null) { WemosNodeBatteryValue bl = new WemosNodeBatteryValue() { NodeID = message.NodeID, TimeStamp = DateTime.Now, Value = (int)message.GetInteger() }; Save(bl); node.LastTimeStamp = bl.TimeStamp; node.LastBatteryValue = bl.Value; node.IPAddress = remoteAddress.CanonicalName; SaveOrUpdate(node); //NotifyMessageReceivedForPlugins(message); //NotifyMessageReceivedForScripts(message); //NotifyForSignalR(new { MsgId = "BatteryValue", Data = bl }); } break; case WemosInternalMessageType.Time: var unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); var sec = Convert.ToInt64(DateTime.Now.Subtract(unixEpoch).TotalSeconds); // seconds since 1970 await Send(new WemosMessage(message.NodeID, message.LineID, WemosMessageType.Internal, (int) WemosInternalMessageType.Time).Set(sec)); break; case WemosInternalMessageType.Version: if (node != null) { node.ProtocolVersion = message.GetFloat(); SaveOrUpdate(node); } break; case WemosInternalMessageType.Config: await Send(new WemosMessage(message.NodeID, -1, WemosMessageType.Internal, (int) WemosInternalMessageType.Config).Set(GetSetting("UnitSystem").Value)); break; case WemosInternalMessageType.FirmwareName: case WemosInternalMessageType.FirmwareVersion: if (node != null) { if (imt == WemosInternalMessageType.FirmwareName) node.FirmwareName = message.GetString(); else node.FirmwareVersion = message.GetFloat(); SaveOrUpdate(node); //NotifyMessageReceivedForPlugins(message); //NotifyMessageReceivedForScripts(message); //NotifyForSignalR(new { MsgId = "NodePresentation", Data = BuildNodeRichWebModel(node) }); } break; } break; #endregion #region Stream //case WemosMessageType.Stream: //used for OTA firmware updates // switch ((StreamValueType) message.SubType) // { // case StreamValueType.FirmwareConfigRequest: // var fwtype = pullWord(payload, 0); // var fwversion = pullWord(payload, 2); // sendFirmwareConfigResponse(sender, fwtype, fwversion, db, gw); // break; // case StreamValueType.FirmwareConfigResponse: // break; // case StreamValueType.FirmwareRequest: // break; // case StreamValueType.FirmwareResponse: // var fwtype = pullWord(payload, 0); // var fwversion = pullWord(payload, 2); // var fwblock = pullWord(payload, 4); // sendFirmwareResponse(sender, fwtype, fwversion, fwblock, db, gw); // break; // case StreamValueType.Sound: // break; // case StreamValueType.Image: // break; // } // break; #endregion } }
public static bool IsMessageFromLine(WemosMessage msg, WemosLine line) { return msg != null && line != null && line.NodeID == msg.NodeID && line.LineID == msg.LineID; }
public virtual void MessageReceived(WemosMessage message) { Process(); }
public virtual void MessageCalibration(WemosMessage message) { }
public abstract bool IsMyMessage(WemosMessage message);