diff --git a/apis/nina/main.go b/apis/nina/main.go
new file mode 100644
index 0000000..9b02686
--- /dev/null
+++ b/apis/nina/main.go
@@ -0,0 +1,89 @@
+package nina
+
+import (
+ "ArinDash/config"
+ "encoding/json"
+ "io"
+ "log"
+ "net/http"
+)
+
+const apiBaseURL = "https://warnung.bund.de/api31"
+
+type configFile struct {
+ Nina ninaConfig
+}
+
+type ninaConfig struct {
+ GebietsCode string
+}
+
+type Warning struct {
+ Id string `json:"id"`
+ Identifier string `json:"identifier"`
+ Sender string `json:"sender"`
+ Sent string `json:"sent"`
+ Status string `json:"status"`
+ MsgType string `json:"msgType"`
+ Scope string `json:"scope"`
+ Code []string `json:"code"`
+ Reference string `json:"reference"`
+ Info []Info `json:"info"`
+}
+
+type Info struct {
+ Language string `json:"language"`
+ Category []string `json:"category"`
+ Event string `json:"event"`
+ Urgency string `json:"urgency"`
+ Severity string `json:"severity"`
+ Expires string `json:"expires"`
+ Headline string `json:"headline"`
+ Description string `json:"description"`
+}
+
+func FetchWarnings() []Warning {
+ cfg := &configFile{}
+ config.LoadConfig(cfg)
+ client := &http.Client{}
+
+ req, err := http.NewRequest("GET", apiBaseURL+"/dashboard/"+cfg.Nina.GebietsCode+".json", nil)
+ if err != nil {
+ panic(err)
+ }
+ resp, err := client.Do(req)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer resp.Body.Close()
+ respBody, err := io.ReadAll(resp.Body)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ warnings := make([]Warning, 0)
+ err = json.Unmarshal(respBody, &warnings)
+ if err != nil {
+ log.Fatal(err)
+ }
+ result := make([]Warning, 0)
+ for _, warning := range warnings {
+ req, err := http.NewRequest("GET", apiBaseURL+"/warnings/"+warning.Id+".json", nil)
+ if err != nil {
+ panic(err)
+ }
+ resp, err := client.Do(req)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer resp.Body.Close()
+ respBody, err := io.ReadAll(resp.Body)
+ if err != nil {
+ log.Fatal(err)
+ }
+ warning := Warning{}
+ err = json.Unmarshal(respBody, &warning)
+ result = append(result, warning)
+ }
+ return result
+}
diff --git a/config_template.toml b/config_template.toml
index f8a7886..9460894 100644
--- a/config_template.toml
+++ b/config_template.toml
@@ -13,3 +13,7 @@ Password = "YourPassword"
#ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city
LocationId = "0000000"
ApiKey = "YourApiKey"
+
+[nina]
+#Code from https://www.xrepository.de/api/xrepository/urn:de:bund:destatis:bevoelkerungsstatistik:schluessel:rs_2021-07-31/download/Regionalschl_ssel_2021-07-31.json
+gebietsCode = "000000000000"
diff --git a/main.go b/main.go
index 6aae481..0a2a105 100644
--- a/main.go
+++ b/main.go
@@ -43,12 +43,14 @@ func initWidgets(ctx context.Context, term *tcell.Terminal) {
widgets.New("HTTPProber", widgets.HTTPProber()),
widgets.New("PiHole", widgets.PiholeStats()),
widgets.New("PiHoleBlocked", widgets.PiholeBlocked()),
+ widgets.New("NinaWarnings", widgets.NinaWarnings()),
)
}
func layout() []container.Option {
builder := grid.New()
builder.Add(
+
grid.ColWidthFixed(84,
grid.RowHeightFixed(44,
grid.Widget(widgets.Get["Wifi"],
@@ -56,7 +58,7 @@ func layout() []container.Option {
container.Border(linestyle.Light),
container.BorderColor(cell.ColorWhite)),
),
- grid.RowHeightFixed(44,
+ grid.RowHeightFixed(46,
grid.Widget(widgets.Get["NetworkDevices"],
container.BorderTitle("Network Devices"),
container.Border(linestyle.Light),
@@ -66,56 +68,76 @@ func layout() []container.Option {
grid.Widget(widgets.Get["empty"]),
),
),
- grid.ColWidthPerc(20,
- grid.RowHeightFixed(8,
- grid.Widget(widgets.Get["Clock"],
- container.AlignHorizontal(align.HorizontalCenter),
- container.BorderTitle("Time"),
- container.Border(linestyle.Light),
- container.BorderColor(cell.ColorWhite),
+
+ grid.ColWidthPerc(58,
+ grid.RowHeightFixed(44,
+ grid.ColWidthFixed(40,
+ grid.RowHeightFixed(8,
+ grid.Widget(widgets.Get["Clock"],
+ container.AlignHorizontal(align.HorizontalCenter),
+ container.BorderTitle("Time"),
+ container.Border(linestyle.Light),
+ container.BorderColor(cell.ColorWhite),
+ ),
+ ),
+ grid.RowHeightFixed(12,
+ grid.Widget(widgets.Get["PiHole"],
+ container.BorderTitle("pi-hole"),
+ container.Border(linestyle.Light),
+ container.BorderColor(cell.ColorWhite),
+ ),
+ ),
+ grid.RowHeightFixed(40,
+ grid.Widget(widgets.Get["PiHoleBlocked"],
+ container.BorderTitle("pi-hole (Blocked Percent)"),
+ container.Border(linestyle.Light),
+ container.BorderColor(cell.ColorWhite),
+ ),
+ ),
+ grid.RowHeightFixed(85,
+ grid.Widget(widgets.Get["empty"]),
+ ),
+ ),
+
+ grid.ColWidthFixed(26,
+ grid.RowHeightFixed(20,
+ grid.Widget(widgets.Get["Calendar"],
+ container.BorderTitle("Calendar"),
+ container.Border(linestyle.Light),
+ container.BorderColor(cell.ColorWhite)),
+ ),
+ grid.RowHeightFixed(25,
+ grid.Widget(widgets.Get["empty"]),
+ ),
+ ),
+
+ grid.ColWidthFixed(25,
+ grid.RowHeightFixed(20,
+ grid.Widget(widgets.Get["Weather"],
+ container.BorderTitle("Weather"),
+ container.Border(linestyle.Light),
+ container.BorderColor(cell.ColorWhite),
+ ),
+ ),
+ grid.RowHeightFixed(85,
+ grid.Widget(widgets.Get["empty"]),
+ ),
),
),
- grid.RowHeightFixed(12,
- grid.Widget(widgets.Get["PiHole"],
- container.BorderTitle("pi-hole"),
- container.Border(linestyle.Light),
- container.BorderColor(cell.ColorWhite),
- ),
- ),
- grid.RowHeightFixed(24,
- grid.Widget(widgets.Get["PiHoleBlocked"],
- container.BorderTitle("pi-hole (Blocked Percent)"),
- container.Border(linestyle.Light),
- container.BorderColor(cell.ColorWhite),
- ),
- ),
- grid.RowHeightPerc(85,
- grid.Widget(widgets.Get["empty"]),
- ),
- ),
- grid.ColWidthPerc(13,
grid.RowHeightFixed(20,
- grid.Widget(widgets.Get["Calendar"],
- container.BorderTitle("Calendar"),
- container.Border(linestyle.Light),
- container.BorderColor(cell.ColorWhite)),
- ),
- grid.RowHeightPerc(25,
- grid.Widget(widgets.Get["empty"]),
- ),
- ),
- grid.ColWidthPerc(25,
- grid.RowHeightFixed(20,
- grid.Widget(widgets.Get["Weather"],
- container.BorderTitle("Weather"),
- container.Border(linestyle.Light),
- container.BorderColor(cell.ColorWhite),
+ grid.RowHeightFixed(25,
+ grid.Widget(widgets.Get["empty"]),
+ ),
+ grid.RowHeightFixed(20,
+ grid.Widget(widgets.Get["NinaWarnings"],
+ container.BorderTitle("BBK Warnings"),
+ container.Border(linestyle.Light),
+ container.BorderColor(cell.ColorWhite),
+ ),
),
),
- grid.RowHeightPerc(25,
- grid.Widget(widgets.Get["empty"]),
- ),
),
+
grid.ColWidthPerc(35,
grid.RowHeightPerc(20,
grid.Widget(widgets.Get["HTTPProber"],
diff --git a/widgets/ninaWarnings.go b/widgets/ninaWarnings.go
new file mode 100644
index 0000000..7604053
--- /dev/null
+++ b/widgets/ninaWarnings.go
@@ -0,0 +1,63 @@
+package widgets
+
+import (
+ "ArinDash/apis/nina"
+ "ArinDash/util"
+ "context"
+ "fmt"
+ "regexp"
+ "time"
+
+ "github.com/mum4k/termdash/cell"
+ "github.com/mum4k/termdash/terminal/terminalapi"
+ "github.com/mum4k/termdash/widgetapi"
+ "github.com/mum4k/termdash/widgets/text"
+)
+
+type NinaWarningsOptions struct {
+}
+
+func NinaWarnings() NinaWarningsOptions {
+ widgetOptions["NinaWarningsOptions"] = createNinaWarnings
+ return NinaWarningsOptions{}
+}
+
+func createNinaWarnings(ctx context.Context, _ terminalapi.Terminal, _ interface{}) widgetapi.Widget {
+ widget := util.PanicOnErrorWithResult(text.New(text.WrapAtWords()))
+
+ go util.Periodic(ctx, 1*time.Minute, func() error {
+ warnings := nina.FetchWarnings()
+ widget.Reset()
+ for _, warning := range warnings {
+ for _, info := range warning.Info {
+ var options []cell.Option
+ if info.Severity == "Moderate" {
+ options = append(options, cell.FgColor(cell.ColorRed))
+ } else if info.Severity == "Minor" {
+ options = append(options, cell.FgColor(cell.ColorYellow))
+ } else if info.Severity == "Fine" {
+ options = append(options, cell.FgColor(cell.ColorGray))
+ } else if info.Severity == "Cancel" {
+ options = append(options, cell.FgColor(cell.ColorGreen))
+ } else {
+ options = append(options, cell.FgColor(cell.ColorRed))
+ options = append(options, cell.Blink())
+ }
+ if err := widget.Write(fmt.Sprintf("%s\n\n", info.Headline), text.WriteCellOpts(append(options, cell.Bold())...)); err != nil {
+ return err
+ }
+ if err := widget.Write(fmt.Sprintf("%s\n\n\n", removeElements(info.Description)), text.WriteCellOpts(options...)); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+ })
+
+ return widget
+}
+func removeElements(input string) string {
+ // Pattern to match content or
+ re := regexp.MustCompile(`.*|
| `)
+ return re.ReplaceAllString(input, "")
+}