Fixed typos in docs
This commit is contained in:
57
README.md
57
README.md
@@ -23,7 +23,7 @@ any kind of internet-based project or device. I already use it on a widget
|
||||
on my phone, on my terminal, on the tmux's status bar, in a couple of
|
||||
smart bedside clocks I've built and as a standalone web app.
|
||||
|
||||
## Basic Usage
|
||||
## Weather
|
||||
As state before, Zephyr talks via HTTP using the JSON format. Therefore, you
|
||||
can query it using any HTTP client of your choice. Below you can find some examples
|
||||
using `curl`:
|
||||
@@ -118,26 +118,30 @@ which yields:
|
||||
{
|
||||
"forecast": [
|
||||
{
|
||||
"condEmoji": "🌧️",
|
||||
"condition": "Rain",
|
||||
"date": "Tuesday, 2025/05/06",
|
||||
"min": "-2°C",
|
||||
"max": "6°C",
|
||||
"condition": "Rain",
|
||||
"emoji": "🌧️",
|
||||
"feelsLike": "0°C",
|
||||
"tempMax": "6°C",
|
||||
"tempMin": "-2°C",
|
||||
"windArrow": "↗️",
|
||||
"windDirection": "SSW",
|
||||
"windSpeed": "14.7 km/h"
|
||||
"wind": {
|
||||
"arrow": "↗️",
|
||||
"direction": "SSW",
|
||||
"speed": "14.7 km/h"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condEmoji": "☃️",
|
||||
"condition": "Snow",
|
||||
"date": "Wednesday, 2025/05/07",
|
||||
"min": "2°C",
|
||||
"max": "9°C",
|
||||
"condition": "Snow",
|
||||
"emoji": "☃️",
|
||||
"feelsLike": "7°C",
|
||||
"tempMax": "9°C",
|
||||
"tempMin": "2°C",
|
||||
"windArrow": "↘️",
|
||||
"windDirection": "NNW",
|
||||
"windSpeed": "13.9 km/h"
|
||||
"wind": {
|
||||
"arrow": "↘️",
|
||||
"direction": "NNW",
|
||||
"speed": "13.9 km/h"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -173,7 +177,7 @@ will yield
|
||||
> $$
|
||||
|
||||
## Statistical analysis
|
||||
In addition to the weather data, Zephyr also provides statistical analysis of pase
|
||||
In addition to the weather data, Zephyr also provides statistical analysis of past
|
||||
meteorological records. This is done through the `/stats/:city` endpoint, which
|
||||
returns additional information about the weather of the previous days such as
|
||||
the average temperature, the maximum and minimum temperatures, the standard deviation,
|
||||
@@ -205,9 +209,7 @@ which yields:
|
||||
"anomaly": null
|
||||
}
|
||||
```
|
||||
After enough data has been collected, the service will also be able to detect
|
||||
anomalies in the temperature data using a built-in statistical model.
|
||||
|
||||
The service is also able to detect anomalies in the temperature data using a built-in statistical model.
|
||||
For instance, two temperature spikes, such as `+34°C` and `-15°C`, with a mean of `25°C` and a standard deviation of `0.2°C`,
|
||||
will be flagged as outliers by the model and will be reported as such:
|
||||
|
||||
@@ -237,14 +239,14 @@ will be flagged as outliers by the model and will be reported as such:
|
||||
The anomaly detection algorithm is based on a modified version of the
|
||||
[Z-Score](https://en.wikipedia.org/wiki/Standard_score) algorithm, which uses the
|
||||
[Median Absolute Deviation](https://en.wikipedia.org/wiki/Median_absolute_deviation) to measure the variability
|
||||
in a given sample of quantitative data. The algorithm can be summarized as follows(let $x$ be the sample):
|
||||
in a given sample of quantitative data. The algorithm can be summarized as follows(let $X$ be the sample):
|
||||
|
||||
|
||||
$$
|
||||
\tilde{x} = \text{median}({X})
|
||||
$$
|
||||
|
||||
Compute The median absolute deviation
|
||||
Compute the median absolute deviation
|
||||
|
||||
$$
|
||||
\text{MAD} = \text{median}\{ |x_i - \tilde{x}| : \forall i = 0, \dots, n-1 \}
|
||||
@@ -258,6 +260,7 @@ $$
|
||||
$$
|
||||
|
||||
Flag $x_i$ as an outlier if:
|
||||
|
||||
$$
|
||||
|z_i| > 4.5
|
||||
$$
|
||||
@@ -276,8 +279,8 @@ These constants have been fine-tuned to work well with the weather data of
|
||||
a wide range of climates and to ignore daily temperature fluctuations while
|
||||
still being able to detect significant anomalies.
|
||||
|
||||
Daily temperatures collected over a short time window(1/2 months, but not less than a few days)
|
||||
// *should* be normally distributed. This algorithm only work under this assumption.
|
||||
According to the Q-Q plots, daily temperatures collected over a time window of no more than 1/2 months
|
||||
but no less than a week, *should* follow a normal distribution.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> The anomaly detection algorithm works under the assumption that the weather data
|
||||
@@ -285,14 +288,13 @@ Daily temperatures collected over a short time window(1/2 months, but not less t
|
||||
> with a very small number of samples(e.g. few days of data) or with a large
|
||||
> number of samples(e.g. multi-seasonal data).
|
||||
|
||||
My statistical benchmarks(QQ plots) show that the algorithm works
|
||||
quite well when these conditions are met, and even with real world data,
|
||||
The algorithm works quite well when these conditions are met, and even with real world data,
|
||||
the results were quite satisfactory. However, if it
|
||||
start to produce false positives, you will need to dump the whole in-memory
|
||||
database and start from scratch. I recommend to do this at every change of season.
|
||||
|
||||
## Embedded Cache System
|
||||
To minimize the amount of requests sent to the OpenWeatherMap API, Zephyr provides an built-in,
|
||||
To minimize the amount of requests sent to the OpenWeatherMap API, Zephyr provides a built-in,
|
||||
in-memory cache data structure that stores fetched weather data. Each time a client requests
|
||||
weather data for a given location, the service will first check if it's already available on the cache.
|
||||
If it is found, the cached value will be returned, otherwise a new request will be sent to the OpenWeatherMap API
|
||||
@@ -309,6 +311,7 @@ Zephyr requires the following environment variables to be set:
|
||||
|
||||
| Variable | Meaning |
|
||||
|----------------------|----------------------------------------|
|
||||
| `ZEPHYR_ADDR` | Listen address |
|
||||
| `ZEPHYR_PORT` | Listen port |
|
||||
| `ZEPHYR_TOKEN` | OpenWeatherMap API key |
|
||||
| `ZEPHYR_CACHE_TTL` | Cache time-to-live(expressed in hours) |
|
||||
@@ -342,4 +345,4 @@ You can run the unit tests by issuing the following command:
|
||||
```
|
||||
|
||||
## License
|
||||
This software is released under the GPLv3 license. You can find a copy of the license with this repository or by visiting the [following page](https://choosealicense.com/licenses/gpl-3.0/).
|
||||
This software is released under the GPLv3 license. You can find a copy of the license with this repository or by visiting the [following page](https://choosealicense.com/licenses/gpl-3.0/).
|
||||
|
||||
Reference in New Issue
Block a user