コード例 #1
0
ファイル: wf_rest.cs プロジェクト: bpaauwe/WFNodeServer
        internal void REST_POST(string url, string content, int len)
        {
            HttpWebRequest  request;
            HttpWebResponse response;
            string          rest_url;
            int             code;

            rest_url = Base + url;

            WFLogging.Debug(rest_url);
            request           = (HttpWebRequest)HttpWebRequest.Create(rest_url);
            request.UserAgent = "WFNodeServer";
            if (AuthRequired)
            {
                request.Headers.Add("Authorization", Authorize());
            }
            request.Proxy         = null;
            request.KeepAlive     = false;
            request.Method        = "POST";
            request.ContentLength = len;
            request.ContentType   = "application/xml";

            Stream datastream = request.GetRequestStream();

            datastream.Write(Encoding.ASCII.GetBytes(content), 0, len);
            datastream.Close();

            try {
                response = (HttpWebResponse)request.GetResponse();
                code     = (int)response.StatusCode;
                response.Close();
            } catch (Exception ex) {
                WFLogging.Error(ex.Message);
            }
        }
コード例 #2
0
ファイル: wf_websocket.cs プロジェクト: bpaauwe/WFNodeServer
 private static void ProcessWSData(string json)
 {
     if (json.Contains("obs_air"))
     {
         WeatherFlowNS.NS.udp_client.WSObservations(json);
     }
     else if (json.Contains("obs_sky"))
     {
         WeatherFlowNS.NS.udp_client.WSObservations(json);
     }
     else if (json.Contains("rapid_wind"))
     {
         WeatherFlowNS.NS.udp_client.RapidWindEvt(json);
     }
     else if (json.Contains("evt_strike"))
     {
         WeatherFlowNS.NS.udp_client.LigtningStrikeEvt(json);
     }
     else if (json.Contains("evt_precip"))
     {
     }
     else if (json.Contains("ack"))
     {
     }
     else
     {
         WFLogging.Error("Unknown type of WebSocket packet");
         WFLogging.Error(json);
     }
 }
コード例 #3
0
        internal static void LogPage(HttpListenerContext context)
        {
            byte[] page;

            // Process changes
            if (context.Request.ContentLength64 > 0)
            {
                int    len  = (int)context.Request.ContentLength64;
                byte[] post = new byte[1024];

                context.Request.InputStream.Read(post, 0, len);
                string resp = Encoding.Default.GetString(post);
                resp = resp.Substring(0, len);

                foreach (string item in resp.Split('&'))
                {
                    string[] pair = item.Split('=');
                    switch (pair[0])
                    {
                    case "sLogLevel":
                        int l = 0;
                        int.TryParse(pair[1], out l);
                        if (l != WF_Config.LogLevel)
                        {
                            WF_Config.LogLevel = l;
                            WFLogging.Level    = (LOG_LEVELS)l;
                            WeatherFlowNS.SaveConfiguration();
                        }
                        break;

                    case "Save":
                        // Look up value of filename and save log to that file
                        string fname = element(resp, "filename");
                        try {
                            using (StreamWriter sw = new StreamWriter(fname)) {
                                sw.Write(WFLogging.ToString());
                            }
                        } catch (Exception ex) {
                            WFLogging.Error(ex.Message);
                        }
                        break;

                    case "Clear":
                        WFLogging.Clear();
                        break;
                    }
                }
            }

            page = ASCIIEncoding.ASCII.GetBytes(MakeLog());

            context.Response.ContentType     = "text/html";
            context.Response.ContentLength64 = page.Length;
            context.Response.AddHeader("Date", DateTime.Now.ToString("r"));
            context.Response.StatusCode = (int)HttpStatusCode.OK;
            context.Response.OutputStream.Write(page, 0, page.Length);
            context.Response.OutputStream.Flush();
            context.Response.OutputStream.Close();
            context.Response.Close();
        }
コード例 #4
0
        internal static void UploadFile(rest Rest, int profile, string resname, string type)
        {
            Assembly assembly;
            string   resourceName;
            string   contents = "";

            // Load resource into string
            assembly     = Assembly.GetExecutingAssembly();
            resourceName = "WFNodeServer.nodesetup." + resname;
            using (Stream stream = assembly.GetManifestResourceStream(resourceName)) {
                using (StreamReader reader = new StreamReader(stream)) {
                    contents = reader.ReadToEnd();
                }
            }

            if (contents.Length > 0)
            {
                // Send to ISY
                // This is just a http post to /rest/ns/profile/<profile>/upload/<type>/<filename>
                Rest.AuthRequired = true;
                try {
                    Rest.REST_POST("ns/profile/" + profile.ToString() + "/upload/" + type + "/" + resname, contents, contents.Length);
                } catch (Exception ex) {
                    WFLogging.Error(resname + " upload failed: " + ex.Message);
                }
            }
        }
コード例 #5
0
        internal bool GetStationMeta(string station_id)
        {
            string               resp;
            RootObject           root;
            JavaScriptSerializer serializer = new JavaScriptSerializer();

            resp = WFRest.REST("/swd/rest/stations/" + station_id + "?api_key=6c8c96f9-e561-43dd-b173-5198d8797e0a");

            if (resp == "")
            {
                return(false);
            }
            if (resp.Contains("ERROR"))
            {
                return(false);
            }

            if (resp != "")
            {
                try {
                    root = serializer.Deserialize <RootObject>(resp);

                    if (root.stations.Count == 0)
                    {
                        return(false);
                    }

                    Latitude  = root.stations[0].latitude;
                    Longitude = root.stations[0].longitude;

                    //Console.WriteLine("latitude:  " + root.stations[0].latitude.ToString());
                    //Console.WriteLine("longitude: " + root.stations[0].longitude.ToString());
                    //Console.WriteLine("elevation: " + root.stations[0].station_meta.elevation.ToString());
                    foreach (Device device in root.stations[0].devices)
                    {
                        // Types that we're interested in are:
                        //   SK - sky
                        //   AR - air
                        //Console.WriteLine("Sensor: " + device.device_id.ToString() + " is " + device.device_type + " -agl = " + device.device_meta.agl.ToString());
                        if (device.device_type == "AR")
                        {
                            Elevation = root.stations[0].station_meta.elevation + device.device_meta.agl;
                            Air       = device.device_id;
                            AirSN     = device.serial_number;
                        }
                        else if (device.device_type == "SK")
                        {
                            Sky   = device.device_id;
                            SkySN = device.serial_number;
                        }
                    }
                } catch (Exception ex) {
                    WFLogging.Error("Error: " + ex.Message);
                    return(false);
                }
            }
            return(true);
        }
コード例 #6
0
        internal void PrecipitationEvt(string json)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();

            try {
                // evt[0] = timestamp
                PreciptObj = serializer.Deserialize <PreciptData>(json);
                WeatherFlowNS.NS.RaiseRainEvent(this, new RainEventArgs(PreciptObj));
            } catch (Exception ex) {
                WFLogging.Error("Failed to deserialize precipitation event: " + ex.Message);
            }
        }
コード例 #7
0
ファイル: wf_rest.cs プロジェクト: bpaauwe/WFNodeServer
        private string MakeRequest(string rest_url)
        {
            HttpWebRequest  request;
            HttpWebResponse response;
            int             code;
            DateTime        start = DateTime.Now;
            string          xml   = "";

            request           = (HttpWebRequest)HttpWebRequest.Create(rest_url);
            request.UserAgent = "WFNodeServer";
            if (AuthRequired)
            {
                request.Headers.Add("Authorization", Authorize());
            }
            request.Proxy = null;
            request.ServicePoint.ConnectionLimit = 10;
            request.Timeout   = 4000;
            request.KeepAlive = true;
            //request.Pipelined = true;

            // Read data from the stream
            try {
                response = (HttpWebResponse)request.GetResponse();
                code     = (int)response.StatusCode;
                if (code != 200)
                {
                    response.Close();
                    throw new RestException(code, response.StatusDescription);
                }

                if (response.ContentLength == 0)
                {
                    return("");
                }

                // sucess with content
                xml = ChunkedRead(response);
                response.Close();
            } catch (WebException ex) {
                if (ex.Status == WebExceptionStatus.ProtocolError)
                {
                    throw new RestException(400, ex.Message);
                }

                WFLogging.Error("GetResponse thew exception: " + ex.Status.ToString());
                throw new RestException(0, ex.Message);
            }

            stats.RequestTime = DateTime.Now.Subtract(start).TotalMilliseconds;
            stats.Count++;
            return(xml);
        }
コード例 #8
0
        internal void LigtningStrikeEvt(string json)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();

            try {
                // evt[0] = timestamp
                // evt[1] = distance (km)
                // evt[2] = energy
                StrikeObj = serializer.Deserialize <StrikeData>(json);
                WeatherFlowNS.NS.RaiseLightningEvent(this, new LightningEventArgs(StrikeObj));
            } catch (Exception ex) {
                WFLogging.Error("Failed to deserialize strike event: " + ex.Message);
            }
        }
コード例 #9
0
ファイル: wf_rest.cs プロジェクト: bpaauwe/WFNodeServer
        // This is handling the SetParent service only at this point but could
        // be expanded to handle other ISY WSDL reuests if needed.
        internal void SendWSDLReqeust(string service, string parent, string node)
        {
            string          url = "http://" + WF_Config.ISY + "/services";
            HttpWebRequest  request;
            HttpWebResponse response;
            string          reqString = "";

            reqString  = "<? version=\'1.0\' encoding=\'utf-8\'?>";
            reqString += "<s:Envelope>";
            reqString += "<s:Body>";
            reqString += "<u:" + service + " xmlns:u=\'urn:udi-com:service:X_Insteon_Lighting_Service:1\'>";

            reqString += "<node>" + node + "</node>";
            reqString += "<nodeType>1</nodeType>";
            reqString += "<parent>" + parent + "</parent>";
            reqString += "<parentType>1</parentType>";

            reqString += "</u:" + service + ">";
            reqString += "</s:Body>";
            reqString += "</s:Envelope>";
            reqString += "\r\n";

            request             = (HttpWebRequest)HttpWebRequest.Create(url);
            request.KeepAlive   = true;
            request.Method      = "POST";
            request.ContentType = "text/xml; charset-utf-8";
            request.Headers.Add("Authorization", Authorize());
            request.Headers.Add("SOAPAction", "urn:udi-com:device:X_Insteon_Lighting_Service:1#" + service);

            Stream data = request.GetRequestStream();

            data.Write(Encoding.ASCII.GetBytes(reqString), 0, reqString.Length);
            data.Flush();
            data.Close();

            response = (HttpWebResponse)request.GetResponse();
            if (response.StatusCode == HttpStatusCode.OK)
            {
                WFLogging.Log("Grouped " + node + " as a child of " + parent);
            }
            else
            {
                WFLogging.Error("Group of " + node + " under " + parent + "failed: " + response.StatusDescription);
            }

            response.Close();

            return;
        }
コード例 #10
0
ファイル: wf_rest.cs プロジェクト: bpaauwe/WFNodeServer
        //
        // Given a REST partial URL, make the connection and return
        // the XML response
        //
        internal string REST(string url)
        {
            string rest_url;
            string resp = "";

            rest_url = Base + url;

            if (rest_url == "")
            {
                WFLogging.Error("ISY REST called with missing URL.");
                WFLogging.Error("  Does this mean there's no connection to an ISY?");
                return("");
            }

            lock (RateLimit) {
                WFLogging.Debug(rest_url);
                int retrys = 0;

                while (retrys < 5)
                {
                    try {
                        resp = MakeRequest(rest_url);
                        break;
                    } catch (RestException re) {
                        if (re.Code != 0)
                        {
                            WFLogging.Error("REST request " + url + " failed " + re.Message);
                            break;
                        }
                        else
                        {
                            // Timeout or failed to get result
                            retrys++;
                            if (retrys == 5)
                            {
                                WFLogging.Error("REST request " + url + " failed after 5 retries with " + re.Message);
                            }
                            Thread.Sleep(50 * retrys);
                        }
                    }
                }
            }
            return(resp);
        }
コード例 #11
0
        internal void RapidWindEvt(string json)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();

            try {
                // evt[0] = timestamp
                // evt[1] = speed (m/s)
                // evt[2] = direction
                WindObj = serializer.Deserialize <WindData>(json);

                StationInfo si = wf_station.FindStationSky(WindObj.serial_number);
                if (si.rapid)
                {
                    WeatherFlowNS.NS.RaiseRapidEvent(this, new RapidEventArgs(WindObj));
                    WeatherFlowNS.NS.RaiseUpdateEvent(this, new UpdateEventArgs((int)WindObj.ob[0], WindObj.serial_number + "_r", DataType.WIND));
                }
            } catch (Exception ex) {
                WFLogging.Error("Failed to deserialize rapid wind event: " + ex.Message);
                WFLogging.Error(json);
            }
        }
コード例 #12
0
ファイル: wf_server.cs プロジェクト: bpaauwe/WFNodeServer
        private bool AddStation(station_form a_form)
        {
            wf_station station = new wf_station(api_key);

            if (station.GetStationMeta(a_form.station_id.ToString()) || (a_form.station_id == 0))
            {
                a_form.air_id    = (a_form.air_id == 0) ? station.Air : a_form.air_id;
                a_form.sky_id    = (a_form.sky_id == 0) ? station.Sky : a_form.sky_id;
                a_form.air_sn    = (a_form.air_sn == "") ? station.AirSN : a_form.air_sn;
                a_form.sky_sn    = (a_form.sky_sn == "") ? station.SkySN : a_form.sky_sn;
                a_form.elevation = (a_form.elevation == 0) ? station.Elevation : a_form.elevation;
                WeatherFlowNS.NS.AddStation(a_form.station_id, a_form.elevation, a_form.air_id, a_form.sky_id, a_form.remote, station.AirSN, station.SkySN, a_form.rapid);
                return(true);
            }
            else
            {
                WFLogging.Error("Failed to find station " + a_form.station_id.ToString());
                cfg_file_status = "Station " + a_form.station_id.ToString() + " lookup failed.";
            }
            return(false);
        }
コード例 #13
0
ファイル: wf_server.cs プロジェクト: bpaauwe/WFNodeServer
 private void Listen()
 {
     using (listener = new HttpListener()) {
         try {
             listener.Prefixes.Add("http://*:" + port.ToString() + "/");
             listener.Start();
         } catch (Exception ex) {
             WFLogging.Error("Failed to start web server on port " + port.ToString());
             WFLogging.Error("  Error was: " + ex.Message);
             return;
         }
         while (true)
         {
             try {
                 HttpListenerContext context = listener.GetContext();
                 Process(context);
             } catch (Exception ex) {
                 WFLogging.Error("Failed to process connection: " + ex.Message);
             }
             //Thread.Sleep(5000);
         }
     }
 }
コード例 #14
0
        // TODO:
        //   How do we want to handle the device status?  There should
        //   be at least 2 devices present (Air & Sky). Do we create
        //   a HS record for each and use that as a place to store the
        //   device specific data?  Or do we just create an internal
        //   list of devivces?
        //
        //   Whatever we do here we should probably do for the hub
        //   as well (treat it as a third device).
        private void DeviceStatus(string json)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();

            try {
                DeviceObj = serializer.Deserialize <DeviceData>(json);

                // Add event to update this info.
                try {
                    WeatherFlowNS.NS.RaiseDeviceEvent(this, new WFNodeServer.DeviceEventArgs(DeviceObj));
                } catch {
                    WFLogging.Warning("Failed to process device event.");
                }
                WeatherFlowNS.NS.RaiseUpdateEvent(this, new UpdateEventArgs((int)DeviceObj.timestamp, DeviceObj.serial_number + "_d", DataType.DEVICE));

                //Console.WriteLine("Serial Number:     " + DeviceObj.serial_number);
                //Console.WriteLine("Device Type:       " + DeviceObj.type);
                //Console.WriteLine("Hub Serial Number: " + DeviceObj.hub_sn);
                //Console.WriteLine("timestamp:         " + DeviceObj.timestamp.ToString());
                //Console.WriteLine("uptime:            " + DeviceObj.uptime.ToString());
                //Console.WriteLine("Voltage:           " + DeviceObj.voltage.ToString());
                //Console.WriteLine("Firmware:          " + DeviceObj.firmware_revision.ToString());
                //Console.WriteLine("RSSI:              " + DeviceObj.rssi.ToString());
                //Console.WriteLine("Sensor status:     " + DeviceObj.sensor_status.ToString());

                if (Sensors.ContainsKey(DeviceObj.serial_number))
                {
                    Sensors[DeviceObj.serial_number] = DeviceObj;
                }
                else
                {
                    Sensors.Add(DeviceObj.serial_number, DeviceObj);
                }
            } catch (Exception ex) {
                WFLogging.Error("Deserialization of device status failed: " + ex.Message);
            }
        }
コード例 #15
0
        private void HubStatus(string json)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();

            try {
                HubObj = serializer.Deserialize <HubData>(json);
                WeatherFlowNS.NS.RaiseHubEvent(this, new WFNodeServer.HubEventArgs(HubObj));
                WeatherFlowNS.NS.RaiseUpdateEvent(this, new UpdateEventArgs((int)HubObj.timestamp, HubObj.serial_number, DataType.HUB));

                //Console.WriteLine("Serial Number:     " + HubObj.serial_number);
                //Console.WriteLine("Device Type:       " + HubObj.type);
                //Console.WriteLine("Firmware:          " + HubObj.firmware_revision.ToString());
                //Console.WriteLine("uptime:            " + HubObj.uptime.ToString());
                //Console.WriteLine("RSSI:              " + HubObj.rssi.ToString());
                //Console.WriteLine("timestamp:         " + HubObj.timestamp.ToString());
                //Console.WriteLine("Reset Flags:       " + HubObj.reset_flags);
                //Console.WriteLine("Stack:             " + HubObj.stack);
                //Console.WriteLine("Sequence:          " + HubObj.seq.ToString());
                //Console.WriteLine("External File:     " + HubObj.fs.ToString());
                ValidHub = true;
            } catch (Exception ex) {
                WFLogging.Error("Deserialization of device status failed: " + ex.Message);
            }
        }
コード例 #16
0
        private void SkyObservations(string json)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();

            try {
                SkyObj       = serializer.Deserialize <SkyData>(json);
                SkyObj.valid = true;

                WFNodeServer.SkyEventArgs evnt = new SkyEventArgs(SkyObj);
                evnt.SetDaily = CalcDailyPrecipitation();
                evnt.Raw      = json;

                try {
                    WeatherFlowNS.NS.RaiseSkyEvent(this, evnt);
                } catch (Exception ex) {
                    WFLogging.Warning("Failed to process Sky event. " + ex.Message);
                }
                WeatherFlowNS.NS.RaiseUpdateEvent(this, new UpdateEventArgs((int)SkyObj.obs[0][0].GetValueOrDefault(), SkyObj.serial_number, DataType.SKY));
            } catch (Exception ex) {
                WFLogging.Error("Deserialization failed for sky data: " + ex.Message);
                WFLogging.Verbose(json);
                return;
            }
        }
コード例 #17
0
        //  Look for UPNP broadcast messages from an ISY. If it finds
        //  one, then use it.
        //
        //  FIXME: How do we know this is the right ISY?  What if there
        //  is more than one on the network?
        internal static string IsyAutoDetect()
        {
            UdpClient  listen_udp;
            IPAddress  group_ip;
            IPEndPoint group_ep;
            string     ip = "";

            byte[] recv_data;
            int    i;
            string buf   = "";
            int    tries = 100;

            using (listen_udp = new UdpClient()) {
                listen_udp.ExclusiveAddressUse = false;
                listen_udp.Client.SetSocketOption(SocketOptionLevel.Socket,
                                                  SocketOptionName.ReuseAddress, true);
                group_ip = IPAddress.Parse("239.255.255.250");
                //group_ep = new IPEndPoint(IPAddress.Any, 1900);
                group_ep = new IPEndPoint(IPAddress.Any, 20034);

                try {
                    listen_udp.Client.Bind(group_ep);
                } catch (Exception e) {
                    WFLogging.Error("Failed to bind to broadcast address");
                    WFLogging.Error(e.Message);
                    return("");
                }

                listen_udp.EnableBroadcast = true;

                try {
                    listen_udp.JoinMulticastGroup(group_ip);
                } catch (Exception e) {
                    WFLogging.Error("Failed to join Multicast group: " + e.Message);
                    //listen_udp.Close();
                    return("");
                }

                // Set the timeout at 90 seconds.  If we haven't received anything in
                // that time, we probably won't.
                listen_udp.Client.ReceiveTimeout = 90000;

                while ((ip == ""))
                {
                    try {
                        recv_data = listen_udp.Receive(ref group_ep);
                    } catch {
                        WFLogging.Error("Timed out trying to discover ISY.");
                        return("");
                    }
                    if (recv_data.Length != 0)
                    {
                        // Found somelthing
                        buf = Encoding.ASCII.GetString(recv_data);

                        // Now see if this is really an ISY
                        if (buf.Contains("X_Insteon") == false)
                        {
                            if (--tries == 0)
                            {
                                WFLogging.Error("Failed to detect ISY on the network.");
                                return("");
                            }
                        }
                        else
                        {
                            // This really is an ISY.  Pull the location field
                            // from the string.
                            i = buf.IndexOf("LOCATION:");
                            if ((i > 0))
                            {
                                ip = buf.Substring((i + 9)).Split('\r')[0];
                            }
                        }
                    }
                }
                listen_udp.DropMulticastGroup(group_ip);
                //listen_udp.Close();
            }

            WFLogging.Log(("Found an ISY: " + ip));
            return(ip);
        }
コード例 #18
0
ファイル: wf_websocket.cs プロジェクト: bpaauwe/WFNodeServer
        internal void Start()
        {
            byte[] buf = new byte[512];
            int    len;
            bool   header = false;

            while (Started)
            {
                int retries = 0;

                WFLogging.Warning("Attempt to start already active WebSocket connection " + retries.ToString());
                Thread.Sleep(1000);

                if (retries++ > 10)
                {
                    WFLogging.Error("Giving up after 10 attempts.");
                    return;
                }
            }

            client = new TcpClient(Host, Port);
            if (!client.Connected)
            {
                WFLogging.Error("Client not connected to " + Port);
            }

            WFLogging.Log("Starting communication with websocket server.");
            finished = false;
            Started  = true;

            // Send header
            var seckeybytes = Encoding.UTF8.GetBytes(seckey);

            client.Client.Send(Encoding.ASCII.GetBytes("GET " + Path + " HTTP/1.1\r\n"));
            client.Client.Send(Encoding.ASCII.GetBytes("Host: " + Host + ":" + Port.ToString() + "\r\n"));
            client.Client.Send(Encoding.ASCII.GetBytes("Upgrade: websocket\r\n"));
            client.Client.Send(Encoding.ASCII.GetBytes("Connection: Upgrade\r\n"));
            client.Client.Send(Encoding.ASCII.GetBytes("Pragma: no-cache\r\n"));
            client.Client.Send(Encoding.ASCII.GetBytes("Origin: http://" + Host + "\r\n"));
            client.Client.Send(Encoding.ASCII.GetBytes("Cache-Control: no-cache\r\n"));
            client.Client.Send(Encoding.ASCII.GetBytes("Sec-WebSocket-Key: " + System.Convert.ToBase64String(seckeybytes) + "\r\n"));
            client.Client.Send(Encoding.ASCII.GetBytes("Sec-WebSocket-Version: 13\r\n"));
            client.Client.Send(Encoding.ASCII.GetBytes("\r\n"));

            WFLogging.Info("    Waiting for handshake");
            Thread.Sleep(100);
            // Receive handshake
            while (!header)
            {
                if (client.Client.Available > 0)
                {
                    len = client.Client.Receive(buf, (client.Client.Available - 1), SocketFlags.None);
                    if (len > 0)
                    {
                        string strbuf = Encoding.ASCII.GetString(buf, 0, len);
                        // Just look for the a websock type response, ignore the rest of the headers
                        if (strbuf.Contains("HTTP/1.1 101"))
                        {
                            header = true;
                        }
                    }
                }
                Thread.Sleep(500);
            }

            receive_thread = new Thread(new ThreadStart(ReceiveLoop));
            receive_thread.IsBackground = true;
            receive_thread.Start();
        }
コード例 #19
0
ファイル: wf_websocket.cs プロジェクト: bpaauwe/WFNodeServer
        private static void ReceiveCallback(IAsyncResult ar)
        {
            StateObject state  = (StateObject)ar.AsyncState;
            TcpClient   client = state.workSocket;

            int bytes_read = client.Client.EndReceive(ar);

            if (bytes_read > 0)
            {
                int    bi   = 0;
                byte[] mask = new byte[4];
                if ((state.buffer[0] & 0x80) == 0x80)
                {
                    int payload_type    = state.buffer[0] & 0x0f;
                    int payload_size    = state.buffer[1] & 0x7f;
                    int payload_masking = state.buffer[1] & 0x80;
                    bi += 2;
                    //Console.WriteLine("type = " + payload_type.ToString() + " mask = " + payload_masking.ToString() + " len = " + payload_size.ToString());
                    if (payload_size == 126)
                    {
                        payload_size = (state.buffer[bi++] << 8) + state.buffer[bi++];
                        //Console.WriteLine("extended size = " + payload_size.ToString());
                    }
                    if (payload_masking == 0x80)
                    {
                        mask[0] = state.buffer[bi++];
                        mask[1] = state.buffer[bi++];
                        mask[2] = state.buffer[bi++];
                        mask[3] = state.buffer[bi++];
                    }

                    if (bytes_read > payload_size)
                    {
                        for (int i = 0; i < payload_size; i++)
                        {
                            if (payload_masking == 0x80)
                            {
                                state.buffer[bi + i] = (byte)(state.buffer[bi + i] ^ mask[i % 4]);
                            }
                        }

                        if (payload_type == 0x01)
                        {
                            // TODO: Text type payload so send it somewhere
                            //Console.WriteLine("Payload: " + Encoding.ASCII.GetString(state.buffer, bi, payload_size));
                            //Program.RaiseEvent(new WSEventArgs(Encoding.ASCII.GetString(state.buffer, bi, payload_size)));
                            ProcessWSData(Encoding.ASCII.GetString(state.buffer, bi, payload_size));
                        }
                        else if (payload_type == 0x02)
                        {
                            // Binary payload
                        }
                        else if (payload_type == 0x00)
                        {
                            WFLogging.Error("Got a continuation opcode, currently not supported.");
                        }
                        else if (payload_type == 0x08)
                        {
                            // Close frame
                            finished = true;
                            SendMessage(client, Encoding.ASCII.GetString(state.buffer, bi, payload_size), 0x08);
                        }
                        else if (payload_type == 0x09)
                        {
                            // Ping so we need to pong
                            SendMessage(client, Encoding.ASCII.GetString(state.buffer, bi, payload_size), 0x0A);
                        }

                        receiveDone.Set();
                        return;
                    }
                    else
                    {
                        // We need to read more data
                        WFLogging.Info("Need more data to complete frame");
                        client.Client.BeginReceive(state.buffer, 0, StateObject.bufsize, 0, new AsyncCallback(ReceiveCallback), state);
                        return;
                    }
                }
            }
            receiveDone.Set();
        }
コード例 #20
0
ファイル: wf_server.cs プロジェクト: bpaauwe/WFNodeServer
        private string MakeConfigPage()
        {
            string page;
            bool   remote_configured     = false;
            bool   nodeserver_configured = false;

            foreach (StationInfo s in WF_Config.WFStationInfo)
            {
                if (s.remote && (s.air_id != 0 || s.sky_id != 0))
                {
                    remote_configured = true;
                }
            }

            if ((WF_Config.Profile > 0) &&
                (WF_Config.Password != "") &&
                (WF_Config.Username != "") &&
                (WF_Config.Port > 0) &&
                (WF_Config.ISY != ""))
            {
                nodeserver_configured = true;
            }

            page  = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html\">\n";
            page += "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n";
            page += "<meta http-equiv=\"expires\" content=\"0\">\n";
            page += "<meta http-equiv=\"pragma\" content=\"no-cache\">\n";
            page += "<meta http-equiv=\"Content-Language\" content=\"en\">\n";
            page += "<meta charset=\"UTF-8\">\n";
            page += "<meta name=\"google\" content=\"notranslate\">\n";
            page += "<style>\n";
            page += "	body { font-family: Sans-Serif; }\n";
            page += "</style>\n";
            page += "<title>WeatherFlow Nodeserver Web Interface</title>\n";
            page += "</head><body>\n";
            page += "<form name=\"root\" action=\"/config\" enctype=\"application/x-www-form-urlencoded\" method=\"post\">\n";
            page += MakeMenu();
            page += "<div style=\"margin: 20 auto; padding-bottom: 10px;\">\n";
            page += "<div>\n";
            page += "<table border=\"0\" width=\"600\" id=\"tblBody\" style=\"padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px\">\n";
            page += "<tr><td colspan=\"3\" Class=\"sectionTitle\"><br><h2>Configuration</h2><br></td></tr>\n";

            page += ConfigItem("Port", "webPort", WF_Config.Port.ToString(), 0);
            page += ConfigItem("ISY Address", "sAddress", WF_Config.ISY, 3);
            page += ConfigItem("ISY Username", "sUsername", WF_Config.Username, 1);
            page += ConfigItem("ISY Password", "sPassword", WF_Config.Password, 2);
            page += ConfigItem("Profile Number", "sProfile", WF_Config.Profile.ToString(), 0);
            page += ConfigBoolItem("Include Hub data", "sHub", WF_Config.Hub);
            page += ConfigBoolItem("Include Device data", "sDevice", WF_Config.Device);
            page += ConfigUnits("Set Units", "sUnits", WF_Config.Units);
            page += ConfigList("Set Logging Level", "sLogLevel", WF_Config.LogLevel);

            page += "<tr>\n";
            page += "<td colspan=\"3\">";
            if (nodeserver_configured)
            {
                page += "<form method=\"post\">";
                page += "<input type=\"submit\" name=\"serverctl\" value=\" Restart Node Server \">";
                page += "&nbsp;";
                page += "<input type=\"submit\" name=\"serverctl\" value=\" Pause Node Server \">";
                page += "&nbsp;";
                page += "<input style=\"width: 120px; text-align: center; background-color: #e8e8e8;\" type=\"text\" name=\"status\" value=\"";
                page += (WeatherFlowNS.NS.udp_client.Active) ? "Running" : "Paused";
                page += "\" readonly>";
                page += "&nbsp;&nbsp;";
                page += "<input type=\"submit\" name=\"upload\" value=\" Upload Profile Files \" placeholder=\"Upload files to the ISY\">";
                page += "</form>";
            }
            page += "</td>\n";
            page += "</tr>\n";

            page += "<tr><th colspan=\"3\">&nbsp;</th></tr>\n";
            page += "</table> </div> </form>\n";

            page += "<div style=\"padding-left: 4px; padding-right: 4px; padding-top: 20px; padding-bottom: 1px\">\n";
            page += "<table border=\"0\">\n";
            page += "<tr><td colspan=\"8\"><h2>Station Configuration</h2></td></tr>\n";
            page += "<tr><th>Station ID</th><th>Sky S/N</th><th>Air S/N</th><th>Elevation (meters)</th><th>Remote</th><th>Rapid</th><th>&nbsp;</th></tr>\n";
            foreach (StationInfo s in WF_Config.WFStationInfo)
            {
                string placeholder = "Enter the weather station ID";

                page += "<tr>";
                page += "<form method=\"post\">";
                if (s.station_id == 0)
                {
                    page += "<td><input style=\"width:150px\" name = \"station_id\" readonly value=\"" + "Local UDP" + "\"></td>";
                }
                else
                {
                    page += "<td><input style=\"width:150px\" required placeholder=\"" + placeholder + "\" name = \"station_id\" type=\"number\" value=\"" + s.station_id.ToString() + "\"></td>";
                }
                //page += "<td><input style=\"width:150px\" type=\"number\" readonly value=\"" + s.sky_id.ToString() + "\"></td>";
                //page += "<td><input style=\"width:150px\" type=\"number\" readonly value=\"" + s.air_id.ToString() + "\"></td>";
                page += "<td><input style=\"width:150px\" readonly value=\"" + s.sky_sn + "\"></td>";
                page += "<td><input style=\"width:150px\" readonly value=\"" + s.air_sn + "\"></td>";
                page += "<td><input style=\"width:150px\" name=\"elevation\" type=\"number\" step=\"any\" value=\"" + s.elevation.ToString() + "\"></td>";
                page += "<td><input style=\"width:50px\" ";
                page += (s.remote) ? "checked" : "unchecked";
                page += " type=\"checkbox\" name=\"remote\" value=\"1\"></td>";
                page += "<td><input style=\"width:50px\" ";
                page += (s.rapid) ? "checked" : "unchecked";
                page += " type=\"checkbox\" name=\"rapid\" value=\"2\"></td>";
                page += "<td><input name=\"stationcfg\" type=\"submit\" value=\"Update\"></td>";
                page += "<td><input name=\"stationcfg\" type=\"submit\" value=\"Delete\"></td>";
                page += "</form></tr>\n";
            }
            // Add input row
            page += "<form name=\"stations\" action=\"/config\" enctype=\"application/x-www-form-urlencoded\" method=\"post\">\n";
            page += "<tr>";
            page += "<td><input style=\"width:150px\" type=\"number\" step=\"any\" name=\"station_id\" value=\"\" required></td>\n";
            //page += "<td><input style=\"width:150px\" type=\"number\" step=\"any\" name=\"sky_id\" value=\"\"></td>\n";
            //page += "<td><input style=\"width:150px\" type=\"number\" step=\"any\" name=\"air_id\" value=\"\"></td>\n";
            page += "<td><input style=\"width:150px\" name=\"sky_id\" value=\"\"></td>\n";
            page += "<td><input style=\"width:150px\" name=\"air_id\" value=\"\"></td>\n";
            page += "<td><input style=\"width:150px\" type=\"number\" step=\"any\" name=\"elevation\" value=\"\"></td>\n";
            page += "<td><input style=\"width:50px\" type=\"checkbox\"  name=\"remote\" value=\"1\"></td>\n";
            page += "<td><input style=\"width:50px\" type=\"checkbox\"  name=\"rapid\" value=\"1\"></td>\n";
            page += "<td><input name=\"stationcfg\" type=\"submit\" value=\"  Add  \"></td>\n";
            page += "</tr>";
            page += "</form>\n";

            page += "<tr>\n";
            page += "<td colspan=\"7\">";
            if (remote_configured)
            {
                page += "<form method=\"post\">\n";
                page += "<input type=\"submit\" name=\"websocket\" value=\" Start WebSocket Client \">";
                page += "&nbsp;";
                page += "<input type=\"submit\" name=\"websocket\" value=\" Stop WebSocket Client \">";
                page += "&nbsp;";
                page += "<input style=\"width: 120px; text-align: center; background-color: #e8e8e8;\" type=\"text\" name=\"wsstatus\" value=\"";
                page += (WeatherFlowNS.NS.wsi.Started) ? "Running" : "Stopped";
                page += "\" readonly>";
                page += "</form>";
            }
            page += "</td>\n";
            page += "</tr>\n";

            page += "</table>\n";
            page += "</div>\n";

            page += "<div style=\"padding-left: 4px; padding-right: 4px; padding-top: 20px; padding-bottom: 1px\">\n";
            page += "<hr>\n";
            page += "<div style=\"border: 1px solid; background-color: #D8D8D8; padding: 2px 2px 2px 2px\">";
            page += "Status: " + cfg_file_status;
            page += "</div>";
            page += "</div>";


            // Display a table of nodes that were found on the ISY
            page += "<div style=\"padding-left: 4px; padding-right: 4px; padding-top: 20px; padding-bottom: 1px\">\n";
            page += "<table width=\"450px\" border=\"1\">\n";
            page += "<tr><th>Node Address</th><th>Node Type</th></tr>\n";
            foreach (string n in WeatherFlowNS.NS.NodeList.Keys)
            {
                try {
                    page += "<tr><td style=\"padding: 1px 1px 1px 5px;\">" + n + "</td>";
                    page += "<td style=\"padding: 1px 1px 1px 5px;\">" + NodeDefs[WeatherFlowNS.NS.NodeList[n]] + "</td></tr>\n";
                } catch {
                    WFLogging.Error("Missing definition for node type " + WeatherFlowNS.NS.NodeList[n]);
                }
            }
            page += "</table>\n";
            page += "</div>\n";

            page += "</div>\n";

            page += "</body> </html> \n";

            return(page);
        }
コード例 #21
0
ファイル: wf_server.cs プロジェクト: bpaauwe/WFNodeServer
        private void ConfigPage(HttpListenerContext context)
        {
            string cfg_page;

            byte[] page;
            byte[] post = new byte[1024];
            Thread do_something;

            //Console.WriteLine("content length = " + context.Request.ContentLength64.ToString());
            if (context.Request.ContentLength64 > 0)
            {
                string[] list;
                string[] pair;
                int      len     = (int)context.Request.ContentLength64;
                bool     initISY = false;
                bool     saveCfg = false;

                context.Request.InputStream.Read(post, 0, len);
                string resp = Encoding.Default.GetString(post);
                resp = resp.Substring(0, len);

                //Console.WriteLine("Response = " + resp);

                cfg_file_status = "";

                if (resp.Contains("stationcfg"))
                {
                    station_form a_form = GetStationInfo(resp);
                    switch (a_form.action)
                    {
                    case "Delete":
                        WFLogging.Info("Delete station " + a_form.station_id.ToString());
                        WeatherFlowNS.NS.DeleteStation(a_form.station_id);
                        saveCfg = true;
                        break;

                    case "++Add++":
                        bool exists = false;
                        WFLogging.Info("Add station " + a_form.station_id.ToString());
                        // Check if station already exists
                        foreach (StationInfo s in WF_Config.WFStationInfo)
                        {
                            if (s.station_id == a_form.station_id)
                            {
                                cfg_file_status = "Station " + a_form.station_id.ToString() + " already exists.";
                                exists          = true;
                                break;
                            }
                        }
                        if (!exists)
                        {
                            saveCfg = AddStation(a_form);
                        }
                        break;

                    case "Update":
                        WFLogging.Info("Update station " + a_form.station_id.ToString());
                        saveCfg = AddStation(a_form);
                        break;

                    default:
                        WFLogging.Warning("Unknown action [" + a_form.action + "]");
                        break;
                    }
                }
                else if (resp.Contains("upload"))
                {
                    // Upload profile files  TODO: Should this be done in a thread?
                    do_something = new Thread(WeatherFlowNS.NS.UpdateProfileFiles);
                    do_something.IsBackground = true;
                    do_something.Start();
                }
                else
                {
                    list = resp.Split('&');
                    foreach (string item in list)
                    {
                        int v = 0;
                        pair    = item.Split('=');
                        pair[1] = HttpUtility.UrlDecode(pair[1]);
                        switch (pair[0])
                        {
                        case "sAddress":
                            if (pair[1] != WF_Config.ISY)
                            {
                                WF_Config.ISY = pair[1];
                                initISY       = true;
                                saveCfg       = true;
                            }
                            break;

                        case "sUsername":
                            if (pair[1] != WF_Config.Username)
                            {
                                WF_Config.Username = pair[1];
                                initISY            = true;
                                saveCfg            = true;
                            }
                            break;

                        case "sPassword":
                            if (pair[1] != WF_Config.Password)
                            {
                                WF_Config.Password = pair[1];
                                initISY            = true;
                                saveCfg            = true;
                            }
                            break;

                        case "sProfile":
                            int.TryParse(pair[1], out v);
                            if (v != WF_Config.Profile)
                            {
                                WF_Config.Profile = v;
                                initISY           = true;
                                saveCfg           = true;
                            }
                            break;

                        case "webPort":
                            int.TryParse(pair[1], out v);
                            if (v != WF_Config.Port)
                            {
                                WF_Config.Port = v;
                                saveCfg        = true;
                            }
                            break;

                        case "sSI":
                            bool imperial = (pair[1] == "1");
                            if (imperial != WF_Config.SI)
                            {
                                WF_Config.SI = (pair[1] == "1");
                                saveCfg      = true;
                            }
                            break;

                        case "sHub":
                            bool hub = (pair[1] == "1");
                            if (hub != WF_Config.Hub)
                            {
                                WF_Config.Hub = (pair[1] == "1");
                                saveCfg       = true;
                            }
                            break;

                        case "sDevice":
                            bool device = (pair[1] == "1");
                            if (device != WF_Config.Device)
                            {
                                WF_Config.Device = (pair[1] == "1");
                                saveCfg          = true;
                            }
                            break;

                        case "sUnits":
                            int.TryParse(pair[1], out v);
                            if (v != WF_Config.Units)
                            {
                                WF_Config.Units = v;
                                saveCfg         = true;
                            }
                            break;

                        case "sLogLevel":
                            int.TryParse(pair[1], out v);
                            if (v != WF_Config.LogLevel)
                            {
                                WF_Config.LogLevel = v;
                                WFLogging.Level    = (LOG_LEVELS)v;
                                saveCfg            = true;
                            }
                            break;

                        case "serverctl":
                            if (pair[1].Contains("Restart"))
                            {
                                WeatherFlowNS.NS.udp_client.Start();
                                WeatherFlowNS.NS.heartbeat.Start();
                                cfg_file_status = "Server Started";
                                Thread.Sleep(400);
                            }
                            else if (pair[1].Contains("Pause"))
                            {
                                WeatherFlowNS.NS.heartbeat.Stop();
                                WeatherFlowNS.NS.udp_client.Stop();
                                cfg_file_status = "Server Paused";
                            }
                            break;

                        case "websocket":
                            if (pair[1].Contains("Start"))
                            {
                                try {
                                    WeatherFlowNS.NS.StartWebSocket();
                                } catch (Exception ex) {
                                    WFLogging.Error("Starting websocket client failed: " + ex.Message);
                                }
                                cfg_file_status = "Websocket Client Started";
                                Thread.Sleep(400);
                            }
                            else if (pair[1].Contains("Stop"))
                            {
                                WeatherFlowNS.NS.wsi.Stop();
                                cfg_file_status = "Websocket Client Stopped";
                                Thread.Sleep(800);
                            }
                            break;

                        default:
                            break;
                        }
                    }
                }

                if (saveCfg)
                {
                    cfg_file_status += WeatherFlowNS.SaveConfiguration();
                }
                if (initISY)
                {
                    WeatherFlowNS.NS.InitializeISY();
                }
            }

            try {
                cfg_page = MakeConfigPage();
            } catch (Exception ex) {
                WFLogging.Error("Failed to make configuration web page.");
                WFLogging.Error(ex.Message);
                context.Response.Close();
                return;
            }
            // How can we substitute values into the page?  May need to dynamically
            // generate the page instead of storing it as a resource.  That would
            // be a bit of a pain.

            page = ASCIIEncoding.ASCII.GetBytes(cfg_page);

            context.Response.ContentType     = "text/html";
            context.Response.ContentLength64 = page.Length;
            context.Response.AddHeader("Date", DateTime.Now.ToString("r"));
            context.Response.StatusCode = (int)HttpStatusCode.OK;
            context.Response.OutputStream.Write(page, 0, page.Length);
            context.Response.OutputStream.Flush();
            context.Response.OutputStream.Close();
            context.Response.Close();
        }
コード例 #22
0
ファイル: wf_server.cs プロジェクト: bpaauwe/WFNodeServer
        private void Process(HttpListenerContext context)
        {
            string filename = context.Request.Url.AbsolutePath;

            //Console.WriteLine(" request = " + filename);

            if (filename.Contains("config") || filename == "/")
            {
                // Handle configuration
                ConfigPage(context);
                return;
            }

            if (filename.Contains("/log"))
            {
                WFWebLog.LogPage(context);
                return;
            }

            if (filename == "/wflog")
            {
                WFWebLog.LogText(context);
                return;
            }

            if (filename == "/nodeinfo")
            {
                WFNodeInfo.NodeDocPage(context);
                return;
            }

            // WeatherFlow/install  - install
            // Weatherflow/nodes/<address>/query - Query the node and report status
            // WeatherFlow/nodes/<address>/status - report current status
            // WeatherFlow/add/nodes - Add all nodes
            //  These could have a ?requestid=<requestid> at the end
            //  that means we need to send a message after completing the task
            // WeatherFlow/nodes/<address>/report/add
            // WeatherFlow/nodes/<address>/report/remove
            // WeatherFlow/nodes/<address>/report/rename
            // WeatherFlow/nodes/<address>/report/enable
            // WeatherFlow/nodes/<address>/report/disable

            // TODO: Parse out the request id if present
            if (filename.Contains("install"))
            {
                WFLogging.Info("Recieved request to install the profile files.");
            }
            else if (filename.Contains("query"))
            {
                string[] parts;
                parts = filename.Split('/');

                WFLogging.Info("Query node " + parts[3]);
            }
            else if (filename.Contains("status"))
            {
                string[] parts;
                parts = filename.Split('/');

                WFLogging.Info("Get status of node " + parts[3]);
                NodeStatus();
            }
            else if (filename.Contains("add"))
            {
                WFLogging.Info("Add our node.  How is this different from report/Add?");
                AddNodes();

                // the report API is not yet implemented on the ISY so we'll
                // never get anything of these until it is.
            }
            else if (filename.Contains("report/add"))
            {
                WFLogging.Info("Report that a node was added?");
            }
            else if (filename.Contains("report/rename"))
            {
            }
            else if (filename.Contains("report/remove"))
            {
            }
            else if (filename.Contains("report/enable"))
            {
            }
            else if (filename.Contains("report/disable"))
            {
            }
            else if (filename.Contains("favicon.ico"))
            {
            }
            else
            {
                WFLogging.Error("Unknown Request: " + filename);
            }

            context.Response.ContentType     = "text/plain";
            context.Response.ContentLength64 = 0;
            context.Response.AddHeader("Date", DateTime.Now.ToString("r"));
            context.Response.StatusCode = (int)HttpStatusCode.OK;
            context.Response.OutputStream.Flush();
            context.Response.OutputStream.Close();
            context.Response.Close();
        }
コード例 #23
0
        internal void WSObservations(string json)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            ObsData obs;
            double  elevation = 0;

            try {
                try {
                    obs = serializer.Deserialize <ObsData>(json);
                } catch (Exception ex) {
                    WFLogging.Error("Deserialization failed for WebSocket data: " + ex.Message);
                    WFLogging.Error(json);
                    return;
                }
                if (json.Contains("obs_sky"))
                {
                    //SkyObj = new SkyData();
                    // The first websocket packet seems to be cached data and it
                    // doesn't include some things like the device serial number.
                    // Without the serial number, we can't really process it
                    if (obs.source == "cache")
                    {
                        return;
                    }
                    SkyObj.device_id         = obs.device_id;
                    SkyObj.firmware_revision = obs.firmware_revision;
                    SkyObj.hub_sn            = obs.hub_sn;
                    SkyObj.obs           = obs.obs;
                    SkyObj.serial_number = obs.serial_number;
                    SkyObj.type          = obs.type;
                    SkyObj.valid         = true;

                    WFNodeServer.SkyEventArgs evnt = new SkyEventArgs(SkyObj);
                    evnt.SetDaily = CalcDailyPrecipitation();
                    evnt.Raw      = json;

                    // This fails the first time, why?
                    WeatherFlowNS.NS.RaiseSkyEvent(this, evnt);
                    WeatherFlowNS.NS.RaiseUpdateEvent(this, new UpdateEventArgs((int)SkyObj.obs[0][0], SkyObj.serial_number, DataType.SKY));
                }
                else if (json.Contains("obs_air"))
                {
                    //AirObj = new AirData();
                    if (obs.source == "cache")
                    {
                        return;
                    }
                    AirObj.device_id         = obs.device_id;
                    AirObj.firmware_revision = obs.firmware_revision;
                    AirObj.hub_sn            = obs.hub_sn;
                    AirObj.obs           = obs.obs;
                    AirObj.serial_number = obs.serial_number;
                    AirObj.type          = obs.type;
                    AirObj.valid         = true;

                    // Look up elevation
                    StationInfo si = wf_station.FindStationAir(AirObj.serial_number);
                    if (si != null)
                    {
                        elevation = si.elevation;
                    }

                    AirEventArgs evnt = new AirEventArgs(AirObj);
                    evnt.SetDewpoint     = 0;
                    evnt.SetApparentTemp = 0;
                    evnt.SetTrend        = 1;
                    evnt.SetSeaLevel     = SeaLevelPressure(AirObj.obs[0][(int)AirIndex.PRESSURE].GetValueOrDefault(), elevation);
                    evnt.Raw             = json;
                    if (SkyObj.valid)
                    {
                        try {
                            evnt.SetDewpoint     = CalcDewPoint();
                            evnt.SetApparentTemp = FeelsLike(AirObj.obs[0][(int)AirIndex.TEMPURATURE].GetValueOrDefault(),
                                                             AirObj.obs[0][(int)AirIndex.HUMIDITY].GetValueOrDefault(),
                                                             SkyObj.obs[0][(int)SkyIndex.WIND_SPEED].GetValueOrDefault());
                            // Trend is -1, 0, 1 while event wants 0, 1, 2
                            evnt.SetTrend = PressureTrend() + 1;
                            // Heat index & Windchill ??
                        } catch {
                        }
                    }
                    else
                    {
                    }

                    WeatherFlowNS.NS.RaiseAirEvent(this, evnt);
                    WeatherFlowNS.NS.RaiseUpdateEvent(this, new UpdateEventArgs((int)AirObj.obs[0][0], AirObj.serial_number, DataType.AIR));
                }
            } catch (Exception ex) {
                WFLogging.Error("Failed to process websocket observation data: " + ex.Message);
                return;
            }
        }
コード例 #24
0
        private void AirObservations(string json)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();

            // obs[0][0] = time (seconds)
            // obs[0][1] = station pressure (MB)
            // obs[0][2] = air temp (c)
            // obs[0][3] = humidity (%)

            // obs[0][4] = lightning count
            // obs[0][5] = avg lightning dist (km)
            // obs[0][6] = battery
            // obs[0][7] = interval (minutes)
            try {
                double elevation = 0;

                AirObj       = serializer.Deserialize <AirData>(json);
                AirObj.valid = true;

                // Look up elevation
                StationInfo si = wf_station.FindStationAir(AirObj.serial_number);
                if (si != null)
                {
                    elevation = si.elevation;
                }

                // Do we just want to raise an event with the data object?
                AirEventArgs evnt = new AirEventArgs(AirObj);
                evnt.SetDewpoint     = 0;
                evnt.SetApparentTemp = 0;
                evnt.SetTrend        = 1;
                evnt.SetSeaLevel     = SeaLevelPressure(AirObj.obs[0][(int)AirIndex.PRESSURE].GetValueOrDefault(), elevation);
                evnt.Raw             = json;
                if (SkyObj.valid)
                {
                    try {
                        evnt.SetDewpoint     = CalcDewPoint();
                        evnt.SetApparentTemp = FeelsLike(AirObj.obs[0][(int)AirIndex.TEMPURATURE].GetValueOrDefault(),
                                                         AirObj.obs[0][(int)AirIndex.HUMIDITY].GetValueOrDefault(),
                                                         SkyObj.obs[0][(int)SkyIndex.WIND_SPEED].GetValueOrDefault());
                        // Trend is -1, 0, 1 while event wants 0, 1, 2
                        evnt.SetTrend = PressureTrend() + 1;
                        // Heat index & Windchill ??
                    } catch {
                    }
                }
                else
                {
                }

                try {
                    WeatherFlowNS.NS.RaiseAirEvent(this, evnt);
                } catch (Exception ex) {
                    WFLogging.Warning("Failed to process Air event. " + ex.Message);
                }
                WeatherFlowNS.NS.RaiseUpdateEvent(this, new UpdateEventArgs((int)AirObj.obs[0][0].GetValueOrDefault(), AirObj.serial_number, DataType.AIR));
            } catch (Exception ex) {
                WFLogging.Error("Deserialization failed for air data: " + ex.Message);
                WFLogging.Verbose(json);
            }
        }
コード例 #25
0
ファイル: wf_udp.cs プロジェクト: bpaauwe/WFNodeServer
        internal void WeatherFlowThread()
        {
            Socket     s;
            IPEndPoint groupEP;
            EndPoint   remoteEP;
            string     json;
            int        len;

            using (s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) {
                s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
                groupEP = new IPEndPoint(IPAddress.Any, Port);
                s.Bind(groupEP);
                remoteEP = (EndPoint)groupEP;
                Active   = true;

                while (Active)
                {
                    if (s.Available == 0)
                    {
                        Thread.Sleep(200);
                        continue;
                    }

                    try {
                        // Listen for UDP packets
                        //byte[] bytes = listener.Receive(ref groupEP);
                        byte[] bytes = new Byte[1500];
                        len = s.ReceiveFrom(bytes, ref remoteEP);
                        if (len > 0)
                        {
                            json = Encoding.ASCII.GetString(bytes, 0, len);

                            if (json.Contains("obs_air"))
                            {
                                //Console.WriteLine(json);
                                AirObservations(json);
                            }
                            else if (json.Contains("obs_sky"))
                            {
                                SkyObservations(json);
                            }
                            else if (json.Contains("rapid_wind"))
                            {
                                RapidWindEvt(json);
                            }
                            else if (json.Contains("evt_strike"))
                            {
                                LigtningStrikeEvt(json);
                            }
                            else if (json.Contains("evt_precip"))
                            {
                                PrecipitationEvt(json);
                            }
                            else if (json.Contains("device_status"))
                            {
                                DeviceStatus(json);
                            }
                            else if (json.Contains("hub_status"))
                            {
                                HubStatus(json);
                            }
                            else if (json.Contains("obs_tower"))
                            {
                                // Skip
                            }
                            else
                            {
                                // Unknown type of packet
                            }
                        }
                    } catch (Exception ex) {
                        WFLogging.Error("UDP Listener failed: " + ex.Message);
                    }
                }
                threadDone.Set();
            }
        }