1
0
Fork 0

Adding upstream version 1.34.4.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-05-24 07:26:29 +02:00
parent e393c3af3f
commit 4978089aab
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
4963 changed files with 677545 additions and 0 deletions

View file

@ -0,0 +1,80 @@
# Fireboard Input Plugin
This plugin gathers real-time temperature data from [fireboard][fireboard]
thermometers.
> [!NOTE]
> You will need to sign up to for the [Fireboard REST API][api] in order to use
> this plugin.
⭐ Telegraf v1.12.0
🏷️ iot
💻 all
[fireboard]: https://www.fireboard.com
[api]: https://docs.fireboard.io/reference/restapi.html
## Global configuration options <!-- @/docs/includes/plugin_config.md -->
In addition to the plugin-specific configuration settings, plugins support
additional global and plugin configuration settings. These settings are used to
modify metrics, tags, and field or create aliases and configure ordering, etc.
See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
[CONFIGURATION.md]: ../../../docs/CONFIGURATION.md#plugins
## Configuration
```toml @sample.conf
# Read real time temps from fireboard.io servers
[[inputs.fireboard]]
## Specify auth token for your account
auth_token = "invalidAuthToken"
## You can override the fireboard server URL if necessary
# url = https://fireboard.io/api/v1/devices.json
## You can set a different http_timeout if you need to
## You should set a string using an number and time indicator
## for example "12s" for 12 seconds.
# http_timeout = "4s"
```
### auth_token
In lieu of requiring a username and password, this plugin requires an
authentication token that you can generate using the [Fireboard REST
API](https://docs.fireboard.io/reference/restapi.html#Authentication).
### url
While there should be no reason to override the URL, the option is available
in case Fireboard changes their site, etc.
### http_timeout
If you need to increase the HTTP timeout, you can do so here. You can set this
value in seconds. The default value is four (4) seconds.
## Metrics
The Fireboard REST API docs have good examples of the data that is available,
currently this input only returns the real time temperatures. Temperature
values are included if they are less than a minute old.
- fireboard
- tags:
- channel
- scale (Celcius; Fahrenheit)
- title (name of the Fireboard)
- uuid (UUID of the Fireboard)
- fields:
- temperature (float, unit)
## Example Output
This section shows example output in Line Protocol format. You can often use
`telegraf --input-filter <plugin-name> --test` or use the `file` output to get
this information.
```text
fireboard,channel=2,host=patas-mbp,scale=Fahrenheit,title=telegraf-FireBoard,uuid=b55e766c-b308-49b5-93a4-df89fe31efd0 temperature=78.2 1561690040000000000
```

View file

@ -0,0 +1,138 @@
//go:generate ../../../tools/readme_config_includer/generator
package fireboard
import (
_ "embed"
"encoding/json"
"errors"
"fmt"
"net/http"
"strconv"
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/config"
"github.com/influxdata/telegraf/plugins/inputs"
)
//go:embed sample.conf
var sampleConfig string
type Fireboard struct {
AuthToken string `toml:"auth_token"`
URL string `toml:"url"`
HTTPTimeout config.Duration `toml:"http_timeout"`
client *http.Client
}
type rtt struct {
Temp float64 `json:"temp"`
Channel int64 `json:"channel"`
DegreeType int `json:"degreetype"`
Created string `json:"created"`
}
type fireboardStats struct {
Title string `json:"title"`
UUID string `json:"uuid"`
LatestTemps []rtt `json:"latest_temps"`
}
func (*Fireboard) SampleConfig() string {
return sampleConfig
}
func (r *Fireboard) Init() error {
if len(r.AuthToken) == 0 {
return errors.New("you must specify an authToken")
}
if len(r.URL) == 0 {
r.URL = "https://fireboard.io/api/v1/devices.json"
}
// Have a default timeout of 4s
if r.HTTPTimeout == 0 {
r.HTTPTimeout = config.Duration(time.Second * 4)
}
r.client.Timeout = time.Duration(r.HTTPTimeout)
return nil
}
func (r *Fireboard) Gather(acc telegraf.Accumulator) error {
// Perform the GET request to the fireboard servers
req, err := http.NewRequest("GET", r.URL, nil)
if err != nil {
return err
}
req.Header.Set("Authorization", "Token "+r.AuthToken)
resp, err := r.client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
// Successful responses will always return status code 200
if resp.StatusCode != http.StatusOK {
if resp.StatusCode == http.StatusForbidden {
return fmt.Errorf("fireboard server responded with %d [Forbidden], verify your authToken", resp.StatusCode)
}
return fmt.Errorf("fireboard responded with unexpected status code %d", resp.StatusCode)
}
// Decode the response JSON into a new stats struct
var stats []fireboardStats
if err := json.NewDecoder(resp.Body).Decode(&stats); err != nil {
return fmt.Errorf("unable to decode fireboard response: %w", err)
}
// Range over all devices, gathering stats. Returns early in case of any error.
for _, s := range stats {
gatherTemps(s, acc)
}
return nil
}
// Return text description of degree type (scale)
func scale(n int) string {
switch n {
case 1:
return "Celcius"
case 2:
return "Fahrenheit"
default:
return ""
}
}
// Gathers stats from a single device, adding them to the accumulator
func gatherTemps(s fireboardStats, acc telegraf.Accumulator) {
// Construct lookup for scale values
for _, t := range s.LatestTemps {
tags := map[string]string{
"title": s.Title,
"uuid": s.UUID,
"channel": strconv.FormatInt(t.Channel, 10),
"scale": scale(t.DegreeType),
}
fields := map[string]interface{}{
"temperature": t.Temp,
}
acc.AddFields("fireboard", fields, tags)
}
}
func newFireboard() *Fireboard {
tr := &http.Transport{ResponseHeaderTimeout: 3 * time.Second}
client := &http.Client{
Transport: tr,
Timeout: 4 * time.Second,
}
return &Fireboard{client: client}
}
func init() {
inputs.Add("fireboard", func() telegraf.Input {
return newFireboard()
})
}

View file

@ -0,0 +1,79 @@
package fireboard
import (
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"strconv"
"testing"
"github.com/stretchr/testify/require"
"github.com/influxdata/telegraf/testutil"
)
func TestFireboard(t *testing.T) {
// Create a test server with the const response JSON
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
if _, err := fmt.Fprintln(w, response); err != nil {
w.WriteHeader(http.StatusInternalServerError)
t.Error(err)
return
}
}))
defer ts.Close()
// Parse the URL of the test server, used to verify the expected host
u, err := url.Parse(ts.URL)
require.NoError(t, err)
// Create a new fb instance with our given test server
fireboard := newFireboard()
fireboard.AuthToken = "b4bb6e6a7b6231acb9f71b304edb2274693d8849"
fireboard.URL = u.String()
// Create a test accumulator
acc := &testutil.Accumulator{}
// Gather data from the test server
err = fireboard.Gather(acc)
require.NoError(t, err)
// Expect the correct values for all known keys
expectFields := map[string]interface{}{
"temperature": float64(79.9),
}
// Expect the correct values for all tags
expectTags := map[string]string{
"title": "telegraf-FireBoard",
"uuid": "b55e766c-b308-49b5-93a4-df89fe31efd0",
"channel": strconv.FormatInt(1, 10),
"scale": "Fahrenheit",
}
acc.AssertContainsTaggedFields(t, "fireboard", expectFields, expectTags)
}
var response = `
[{
"id": 99999,
"title": "telegraf-FireBoard",
"created": "2019-03-23T16:48:32.152010Z",
"uuid": "b55e766c-b308-49b5-93a4-df89fe31efd0",
"hardware_id": "XXXXXXXXX",
"latest_temps": [
{
"temp": 79.9,
"channel": 1,
"degreetype": 2,
"created": "2019-06-25T06:07:10Z"
}
],
"last_templog": "2019-06-25T06:06:40Z",
"model": "FBX11E",
"channel_count": 6,
"degreetype": 2
}]
`

View file

@ -0,0 +1,10 @@
# Read real time temps from fireboard.io servers
[[inputs.fireboard]]
## Specify auth token for your account
auth_token = "invalidAuthToken"
## You can override the fireboard server URL if necessary
# url = https://fireboard.io/api/v1/devices.json
## You can set a different http_timeout if you need to
## You should set a string using an number and time indicator
## for example "12s" for 12 seconds.
# http_timeout = "4s"