get basic functionality worknig

This commit is contained in:
Aaron Bieber 2024-08-23 20:42:03 -06:00
parent 2e01a4048d
commit 256ca8c9a8
No known key found for this signature in database
4 changed files with 127 additions and 83 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
*.bak *.bak
result result
tags tags
fass

View File

@ -2,6 +2,6 @@ Website = "https://github.com/qbit/fass"
[Details] [Details]
Icon = "toggleswitch.png" Icon = "toggleswitch.png"
Name = "FyneHome" Name = "fass"
ID = "dev.suah.fass" ID = "dev.suah.fass"
Version = "1.0.0" Version = "1.0.0"

View File

@ -1,5 +1,5 @@
{ {
description = "thing: stuff and things"; description = "fass: stuff and fass";
inputs.nixpkgs.url = "nixpkgs/nixos-unstable"; inputs.nixpkgs.url = "nixpkgs/nixos-unstable";
@ -14,22 +14,23 @@
nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; }); nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; });
in in
{ {
overlay = _: prev: { inherit (self.packages.${prev.system}) thing; }; overlay = _: prev: { inherit (self.packages.${prev.system}) fass; };
packages = forAllSystems (system: packages = forAllSystems (system:
let let
pkgs = nixpkgsFor.${system}; pkgs = nixpkgsFor.${system};
in in
{ {
thing = with pkgs; pkgs.buildGoModule { fass = with pkgs; pkgs.buildGoModule rec {
pname = "thing"; pname = "fass";
version = "v0.0.0"; version = "v0.0.0";
src = ./.; src = ./.;
vendorHash = pkgs.lib.fakeSha256; vendorHash = "sha256-RY8ExxmgfKdEcmV8FLM8mhr/CKAL3pPjgzW7zR1HCv4=";
nativeBuildInputs = [ pkg-config copyDesktopItems ]; nativeBuildInputs = [ pkg-config copyDesktopItems ];
buildInputs = [ buildInputs = [
fyne
glfw glfw
libGL libGL
libGLU libGLU
@ -44,18 +45,20 @@
xorg.xinput xorg.xinput
]; ];
desktopItems = [ buildPhase = ''
(makeDesktopItem { ${fyne}/bin/fyne package
name = "traygent"; '';
exec = pname;
icon = pname; installPhase = ''
desktopName = pname; mkdir -p $out
}) pkg="$PWD/${pname}.tar.xz"
]; cd $out
tar --strip-components=1 -xvf $pkg
'';
}; };
}); });
defaultPackage = forAllSystems (system: self.packages.${system}.thing); defaultPackage = forAllSystems (system: self.packages.${system}.fass);
devShells = forAllSystems (system: devShells = forAllSystems (system:
let let
pkgs = nixpkgsFor.${system}; pkgs = nixpkgsFor.${system};

176
main.go
View File

@ -2,24 +2,41 @@ package main
import ( import (
"fmt" "fmt"
"io"
"log" "log"
"os"
"fyne.io/fyne/v2" "fyne.io/fyne/v2"
"fyne.io/fyne/v2/app" "fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container" "fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/driver/desktop" "fyne.io/fyne/v2/driver/desktop"
"fyne.io/fyne/v2/storage"
"fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
"github.com/pawal/go-hass" "github.com/pawal/go-hass"
) )
type Device struct { func loadData(h *hass.Access, lightCards *[]fyne.CanvasObject, switchCards *[]fyne.CanvasObject) {
Group string lights, err := h.FilterStates("light")
} if err != nil {
log.Fatalln(err)
}
switches, err := h.FilterStates("switch")
if err != nil {
log.Fatalln(err)
}
type State struct { for entity := range lights {
Devices []Device e := lights[entity]
card := makeEntity(e, h)
*lightCards = append(*lightCards, card)
}
for entity := range switches {
e := switches[entity]
card := makeEntity(e, h)
*switchCards = append(*switchCards, card)
}
} }
func getDevice(id string, h *hass.Access) (hass.Device, error) { func getDevice(id string, h *hass.Access) (hass.Device, error) {
@ -54,21 +71,90 @@ func makeEntity(e hass.State, h *hass.Access) *widget.Card {
)) ))
} }
func main() { func loadSavedData(a fyne.App, input *widget.Entry, file string) {
token := os.Getenv("HAAS_TOKEN") uri, err := storage.Child(a.Storage().RootURI(), file)
h := hass.NewAccess("https://home.bold.daemon", "")
h.SetBearerToken(token)
err := h.CheckAPI()
if err != nil { if err != nil {
log.Fatalln(err) return
} }
reader, err := storage.Reader(uri)
if err != nil {
return
}
defer reader.Close()
content, err := io.ReadAll(reader)
if err != nil {
return
}
input.SetText(string(content))
}
func saveData(a fyne.App, w fyne.Window, input *widget.Entry, file string) {
uri, err := storage.Child(a.Storage().RootURI(), file)
if err != nil {
dialog.ShowError(err, w)
return
}
writer, err := storage.Writer(uri)
if err != nil {
dialog.ShowError(err, w)
return
}
defer writer.Close()
_, err = writer.Write([]byte(input.Text))
if err != nil {
dialog.ShowError(err, w)
return
}
dialog.ShowInformation("Success", "", w)
}
func main() {
a := app.New() a := app.New()
w := a.NewWindow("faas") w := a.NewWindow("fass")
if w == nil { if w == nil {
log.Fatalln("unable to create window") log.Fatalln("unable to create window")
} }
var lightCards []fyne.CanvasObject
var switchCards []fyne.CanvasObject
haFile, _ := storage.Child(a.Storage().RootURI(), "haurl")
haExists, _ := storage.Exists(haFile)
tokenFile, _ := storage.Child(a.Storage().RootURI(), "hatoken")
tkExists, _ := storage.Exists(tokenFile)
urlEntry := widget.NewEntry()
passEntry := widget.NewPasswordEntry()
loadSavedData(a, urlEntry, "haurl")
loadSavedData(a, passEntry, "hatoken")
h := hass.NewAccess(urlEntry.Text, "")
if haExists && tkExists {
h.SetBearerToken(passEntry.Text)
err := h.CheckAPI()
if err != nil {
dialog.ShowError(err, w)
} else {
loadData(h, &lightCards, &switchCards)
}
}
settingsForm := &widget.Form{
Items: []*widget.FormItem{
{Text: "Home Assistant URL:", Widget: urlEntry},
{Text: "Access Token:", Widget: passEntry},
{Text: "", Widget: widget.NewButton("Save", func() {
saveData(a, w, urlEntry, "haurl")
saveData(a, w, passEntry, "hatoken")
})},
},
}
ctrlQ := &desktop.CustomShortcut{KeyName: fyne.KeyQ, Modifier: fyne.KeyModifierControl} ctrlQ := &desktop.CustomShortcut{KeyName: fyne.KeyQ, Modifier: fyne.KeyModifierControl}
ctrlW := &desktop.CustomShortcut{KeyName: fyne.KeyW, Modifier: fyne.KeyModifierControl} ctrlW := &desktop.CustomShortcut{KeyName: fyne.KeyW, Modifier: fyne.KeyModifierControl}
w.Canvas().AddShortcut(ctrlQ, func(shortcut fyne.Shortcut) { w.Canvas().AddShortcut(ctrlQ, func(shortcut fyne.Shortcut) {
@ -78,75 +164,29 @@ func main() {
w.Hide() w.Hide()
}) })
lights, err := h.FilterStates("light")
if err != nil {
log.Fatalln(err)
}
switches, err := h.FilterStates("switch")
if err != nil {
log.Fatalln(err)
}
var lightCards []fyne.CanvasObject
var switchCards []fyne.CanvasObject
for entity := range lights {
e := lights[entity]
card := makeEntity(e, h)
lightCards = append(lightCards, card)
}
for entity := range switches {
e := switches[entity]
card := makeEntity(e, h)
switchCards = append(switchCards, card)
}
tabs := container.NewAppTabs( tabs := container.NewAppTabs(
container.NewTabItemWithIcon("Lights", container.NewTabItemWithIcon("Lights",
theme.VisibilityIcon(), theme.VisibilityIcon(),
container.NewVBox( container.NewVBox(
widget.NewCard("All Lights", "", container.NewVBox(
widget.NewButton("On", func() {
for entity := range lights {
e := lights[entity]
dev, err := getDevice(e.EntityID, h)
if err != nil {
log.Println(err)
return
}
dev.On()
}
}),
widget.NewButton("Off", func() {
for entity := range lights {
e := lights[entity]
dev, err := getDevice(e.EntityID, h)
if err != nil {
log.Println(err)
return
}
dev.Off()
}
}),
)),
container.NewAdaptiveGrid(3, lightCards...), container.NewAdaptiveGrid(3, lightCards...),
)), )),
container.NewTabItemWithIcon("Switches", container.NewTabItemWithIcon("Switches",
theme.RadioButtonIcon(), theme.RadioButtonIcon(),
container.NewVBox( container.NewVBox(
widget.NewCard("All Switches", "", container.NewVBox(
widget.NewButton("On", func() {
}),
widget.NewButton("Off", func() {
}),
)),
container.NewAdaptiveGrid(3, switchCards...), container.NewAdaptiveGrid(3, switchCards...),
), ),
), ),
) )
tabs.SetTabLocation(container.TabLocationLeading) tabs.SetTabLocation(container.TabLocationLeading)
w.SetContent(tabs)
w.SetContent(
container.NewAppTabs(
container.NewTabItem("Toggles", tabs),
container.NewTabItem("Settings", container.NewStack(
settingsForm,
)),
),
)
w.SetCloseIntercept(func() { w.SetCloseIntercept(func() {
w.Hide() w.Hide()
}) })