public void TestReadStationValues()
        {
            var api      = new EnvAgencyRainfall();
            var stations = api.GetStations(51.0899, -0.4547, 20);

            Assert.NotNull(stations);

            foreach (var s in stations.items)
            {
                if (s.measures == null || s.measures.Count == 0)
                {
                    continue;
                }
                var rainfallMeasure = s.measures.Find(x => x.parameter.Equals("rainfall"));
                if (rainfallMeasure == null)
                {
                    continue;
                }

                var measurement = api.GetLatestMeasurement(s.stationReference);
                if (measurement.items != null && measurement.items.Count > 0)
                {
                    foreach (var i in measurement.items)
                    {
                        if (!i.parameter.Equals("rainfall"))
                        {
                            continue;
                        }
                        Console.WriteLine($"{s.stationReference} : {s.lat},{s.lon} : {i.latestReading.value}{i.unitName}");
                    }
                }
            }
        }
示例#2
0
        static void update(EnvAgencyRainfall api, EnvAgencyRainfall.GetStationsData stations, InfluxDBClient influxDBClient)
        {
            // Write Data to influx
            using (var writeApi = influxDBClient.GetWriteApi())
            {
                foreach (var s in stations.items)
                {
                    if (s.measures == null || s.measures.Count == 0)
                    {
                        continue;
                    }
                    var rainfallMeasure = s.measures.Find(x => x.parameter.Equals("rainfall"));
                    if (rainfallMeasure == null)
                    {
                        continue;
                    }

                    var measurement = api.GetLatestMeasurement(s.stationReference);
                    if (measurement == null)
                    {
                        // TODO: One instance of this is a rainfall sensor returning value: [0, 0.4], as array instead of single value
                        // There doesn't appear to be anything in the api to signify this, will need to read the docs to tell if it's
                        // an actual error. No big deal really just that sensor won't be read
                        continue;
                    }
                    if (measurement.items != null && measurement.items.Count > 0)
                    {
                        foreach (var i in measurement.items)
                        {
                            if (!i.parameter.Equals("rainfall"))
                            {
                                continue;
                            }

                            var absReading  = i.latestReading.value;
                            var mmPerPeriod = absReading;
                            if (!i.unit.Equals("http://qudt.org/1.1/vocab/unit#Millimeter"))
                            {
                                // Again TODO - Ignore for now as most sensors seem to be mm based.
                                // Should just scale up and we'd be good
                                continue;
                            }
                            var mmPerHour = mmPerPeriod * (3600.0 / i.period);

                            Console.WriteLine($"{s.stationReference} : {s.lat},{s.lon} : {mmPerHour}mm/h");
                            /// ///////////////////////////////////////////

                            // TODO: Take actual timestamp from rainfall reading. This is currently just polling, so less accurate/etc
                            var point = PointData.Measurement("rainfall")
                                        .Tag("location", s.stationReference)
                                        .Field("value", mmPerHour)
                                        .Timestamp(DateTime.UtcNow, WritePrecision.S);

                            writeApi.WritePoint(BucketName, OrgName, point);
                        }
                    }
                }
            }
        }
示例#3
0
        static async System.Threading.Tasks.Task <int> Main(string[] args)
        {
            // Polling interval (seconds)
            var pollingIntervalEnv = Environment.GetEnvironmentVariable("WEATHER_POLLING_INTERVAL");
            var latEnv             = Environment.GetEnvironmentVariable("WEATHER_LATITUDE");
            var lonEnv             = Environment.GetEnvironmentVariable("WEATHER_LONGITUDE");
            var distEnv            = Environment.GetEnvironmentVariable("WEATHER_RADIUSKM");
            var dbConnection       = Environment.GetEnvironmentVariable("INFLUXDB_URL");

            BucketName = Environment.GetEnvironmentVariable("INFLUXDB_DB");

            if (string.IsNullOrEmpty(pollingIntervalEnv) ||
                string.IsNullOrEmpty(latEnv) ||
                string.IsNullOrEmpty(lonEnv) ||
                string.IsNullOrEmpty(distEnv))
            {
                Console.WriteLine("Failed to read environment vars");
                return(1);
            }

            Console.WriteLine("Weather Fetcher Initialising:");
            Console.WriteLine($"\tLATITUDE:{latEnv}");
            Console.WriteLine($"\tLONGITUDE:{lonEnv}");
            Console.WriteLine($"\tDISTANCE:{distEnv}");
            Console.WriteLine($"\tPOLLING_INTERVAL:{pollingIntervalEnv}");
            Console.WriteLine($"\tINFLUXDB_URL:{dbConnection}");
            Console.WriteLine($"\tINFLUXDB_DB:{BucketName}");

            var pollingInterval = 60;

            int.TryParse(pollingIntervalEnv, out pollingInterval);
            var lat = 0.0;

            double.TryParse(latEnv, out lat);
            var lon = 0.0;

            double.TryParse(lonEnv, out lon);
            var dist = 30;

            int.TryParse(distEnv, out dist);

            var api = new EnvAgencyRainfall();
            // Read list of stations once on startup, assume we'll be restarted whenever params change, or to pull in new stations
            var stations = api.GetStations(lat, lon, dist);

            if (stations == null)
            {
                Console.WriteLine("Failed to acquire any stations, try increasing the search radius?");
                return(1);
            }

            using (var influxDBClient = InfluxDBClientFactory.Create(dbConnection, InfluxToken))
            {
                // Start processing, and run until killed
                // TODO: Just polling the api like this isn't the best approach, as it can give us a list of measurements since X time
                // TODO: But it's a quick way to get things going. Best to poll once a minute or 3, looks like all the local stations
                // to me provide mm rainfall per 15-minute intervals so no need to spam too much
                while (true)
                {
                    update(api, stations, influxDBClient);
                    Thread.Sleep(pollingInterval * 1000);
                }
            }
        }