get basic functionality worknig
This commit is contained in:
parent
2e01a4048d
commit
256ca8c9a8
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@
|
|||||||
*.bak
|
*.bak
|
||||||
result
|
result
|
||||||
tags
|
tags
|
||||||
|
fass
|
@ -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"
|
||||||
|
31
flake.nix
31
flake.nix
@ -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
176
main.go
@ -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()
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user