From 72f5de71f30c7793dabcc187159457f0f56d45c8 Mon Sep 17 00:00:00 2001 From: Xevion Date: Sun, 27 Oct 2024 01:29:50 -0500 Subject: [PATCH] feat: initial --- README.md | 19 +++++++ closed.ico | Bin 0 -> 7797 bytes go.mod | 25 +++++++++ go.sum | 112 ++++++++++++++++++++++++++++++++++++++++ main.go | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++ open.ico | Bin 0 -> 7673 bytes unknown.ico | Bin 0 -> 7011 bytes 7 files changed, 300 insertions(+) create mode 100644 README.md create mode 100644 closed.ico create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 open.ico create mode 100644 unknown.ico diff --git a/README.md b/README.md new file mode 100644 index 0000000..5c2974e --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# hass-tray + +A simple Go application to display basic state details (via a tray icon) from a Home Assistant instance. + +- Ultra simple configuration + - YAML configuration file + - Environment variables + - Dotenv file +- Resistant to poor network conditions +- Lightweight, simple icons, simple UI options + +## Wishlist + +- [ ] Handle disconnections, reconnect automatically +- [ ] Event listening with watchdog +- [ ] Rotating System Logs +- [ ] Tray Icon Context Menu (Quit, Refresh, Open Log, Open Home Assistant) +- [ ] State Change Icons + - Icons that better show recent state changes (e.g. Orange for recently closed, Purple for bad connection) \ No newline at end of file diff --git a/closed.ico b/closed.ico new file mode 100644 index 0000000000000000000000000000000000000000..ecf7c992477909a0c38852297854298881056cc0 GIT binary patch literal 7797 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 literal 0 HcmV?d00001 diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..dee36e7 --- /dev/null +++ b/go.mod @@ -0,0 +1,25 @@ +module xevion.dev/hass-tray + +go 1.23.1 + +require ( + github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 // indirect + github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7 // indirect + github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7 // indirect + github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 // indirect + github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55 // indirect + github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f // indirect + github.com/getlantern/systray v1.2.2 // indirect + github.com/go-stack/stack v1.8.0 // indirect + github.com/gobuffalo/envy v1.10.2 // indirect + github.com/gobuffalo/packd v1.0.2 // indirect + github.com/gobuffalo/packr v1.30.1 // indirect + github.com/golang-module/carbon v1.7.1 // indirect + github.com/gorilla/websocket v1.5.0 // indirect + github.com/joho/godotenv v1.5.1 // indirect + github.com/nathan-osman/go-sunrise v1.1.0 // indirect + github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect + github.com/rogpeppe/go-internal v1.9.0 // indirect + golang.org/x/sys v0.1.0 // indirect + saml.dev/gome-assistant v0.2.3 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..19c9286 --- /dev/null +++ b/go.sum @@ -0,0 +1,112 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 h1:NRUJuo3v3WGC/g5YiyF790gut6oQr5f3FBI88Wv0dx4= +github.com/getlantern/context v0.0.0-20190109183933-c447772a6520/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY= +github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7 h1:6uJ+sZ/e03gkbqZ0kUG6mfKoqDb4XMAzMIwlajq19So= +github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7/go.mod h1:l+xpFBrCtDLpK9qNjxs+cHU6+BAdlBaxHqikB6Lku3A= +github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7 h1:guBYzEaLz0Vfc/jv0czrr2z7qyzTOGC9hiQ0VC+hKjk= +github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7/go.mod h1:zx/1xUUeYPy3Pcmet8OSXLbF47l+3y6hIPpyLWoR9oc= +github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 h1:micT5vkcr9tOVk1FiH8SWKID8ultN44Z+yzd2y/Vyb0= +github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7/go.mod h1:dD3CgOrwlzca8ed61CsZouQS5h5jIzkK9ZWrTcf0s+o= +github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55 h1:XYzSdCbkzOC0FDNrgJqGRo8PCMFOBFL9py72DRs7bmc= +github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55/go.mod h1:6mmzY2kW1TOOrVy+r41Za2MxXM+hhqTtY3oBKd2AgFA= +github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f h1:wrYrQttPS8FHIRSlsrcuKazukx/xqO/PpLZzZXsF+EA= +github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA= +github.com/getlantern/systray v1.2.2 h1:dCEHtfmvkJG7HZ8lS/sLklTH4RKUcIsKrAD9sThoEBE= +github.com/getlantern/systray v1.2.2/go.mod h1:pXFOI1wwqwYXEhLPm9ZGjS2u/vVELeIgNMY5HvhHhcE= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.10.2 h1:EIi03p9c3yeuRCFPOKcSfajzkLb3hrRjEpHGI8I2Wo4= +github.com/gobuffalo/envy v1.10.2/go.mod h1:qGAGwdvDsaEtPhfBzb3o0SfDea8ByGn9j8bKmVft9z8= +github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= +github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= +github.com/gobuffalo/packd v1.0.2 h1:Yg523YqnOxGIWCp69W12yYBKsoChwI7mtu6ceM9Bwfw= +github.com/gobuffalo/packd v1.0.2/go.mod h1:sUc61tDqGMXON80zpKGp92lDb86Km28jfvX7IAyxFT8= +github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg= +github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk= +github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw= +github.com/golang-module/carbon v1.7.1 h1:EDPV0YjxeS2kE2cRedfGgDikU6l5D79HB/teHuZDLu8= +github.com/golang-module/carbon v1.7.1/go.mod h1:M/TDTYPp3qWtW68u49dLDJOyGmls6L6BXdo/pyvkMaU= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= +github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lxn/walk v0.0.0-20210112085537-c389da54e794/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= +github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/nathan-osman/go-sunrise v1.1.0 h1:ZqZmtmtzs8Os/DGQYi0YMHpuUqR/iRoJK+wDO0wTCw8= +github.com/nathan-osman/go-sunrise v1.1.0/go.mod h1:RcWqhT+5ShCZDev79GuWLayetpJp78RSjSWxiDowmlM= +github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw= +github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +gopkg.in/Knetic/govaluate.v3 v3.0.0/go.mod h1:csKLBORsPbafmSCGTEh3U7Ozmsuq8ZSIlKk1bcqph0E= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +saml.dev/gome-assistant v0.2.3 h1:WuT0yMuUjyM78eHYjry/mbhMypSZ7GKmc4vr+Y4YOQ4= +saml.dev/gome-assistant v0.2.3/go.mod h1:NAj56yKBq4PXmHIdrn9oeTmM5SHaNYoLfSWpzTpKjXY= diff --git a/main.go b/main.go new file mode 100644 index 0000000..25e3ff1 --- /dev/null +++ b/main.go @@ -0,0 +1,144 @@ +package main + +import ( + "log/slog" + "os" + "os/signal" + + "github.com/getlantern/systray" + dotenv "github.com/joho/godotenv" + ga "saml.dev/gome-assistant" +) + +var ( + doorIdentifier = "binary_sensor.bedroom_door_opening" + service *ga.Service + log *slog.Logger + stateChannel chan string +) + +func HandleState(newState string) { + switch newState { + case "on": + stateChannel <- "open" + case "off": + stateChannel <- "closed" + default: + slog.Error("unknown state encountered", "newState", newState) + stateChannel <- "unknown" + } +} + +func setupHomeAssistant() { + // Connect to Home Assistant + app, err := ga.NewApp(ga.NewAppRequest{ + IpAddress: "home.imfucked.lol", // Replace with your Home Assistant IP Address + HAAuthToken: os.Getenv("HA_AUTH_TOKEN"), + HomeZoneEntityId: "zone.home", + Port: "443", + Secure: true, + }) + if err != nil { + log.Error("Error connecting to Home Assistant", "error", err) + os.Exit(1) + } + defer func() { + app.Cleanup() + log.Debug("Deferred!") + }() + + service = app.GetService() + + // Get the initial state + state, err := app.GetState().Get(doorIdentifier) + if err != nil { + slog.Error("Unable to get initial state", "error", err) + } else { + slog.Debug("Initial State Received") + HandleState(state.State) + } + + app.RegisterEntityListeners(ga. + NewEntityListener(). + EntityIds(doorIdentifier). + Call(func(service *ga.Service, state ga.State, sensor ga.EntityData) { + slog.Debug("Event Received", "identifier", doorIdentifier, "sensor", sensor) + HandleState(sensor.ToState) + }). + Build()) + + app.Start() +} + +func main() { + dotenv.Load() + stateChannel = make(chan string) + + slog.SetDefault(slog.New(slog.NewJSONHandler( + os.Stdout, + &slog.HandlerOptions{ + Level: slog.LevelDebug, + }, + ))) + slog.Info("Starting hass-tray") + + go setupHomeAssistant() + systray.Run(onReady, onExit) +} + +func onReady() { + systray.SetTitle("hass-tray") + systray.SetTooltip("Refreshed") + menuQuit := systray.AddMenuItem("Quit", "Stops the application") + menuOpenLogs := systray.AddMenuItem("Open Logs", "Opens the logs in the default editor") + menuOpenLogs.Disable() + + // Load icons + openIcon, err := os.ReadFile("open.ico") + if err != nil { + slog.Error("Unable to load icon", "error", err) + os.Exit(1) + } + closedIcon, err := os.ReadFile("closed.ico") + if err != nil { + slog.Error("Unable to load icon", "error", err) + os.Exit(1) + } + unknownIcon, err := os.ReadFile("unknown.ico") + if err != nil { + slog.Error("Unable to load icon", "error", err) + os.Exit(1) + } else { + slog.Debug("Icons loaded") + } + systray.SetIcon(unknownIcon) + + // Handle Ctrl+C interrupt + interruptChannel := make(chan os.Signal, 1) + signal.Notify(interruptChannel, os.Interrupt) + signal.Notify(interruptChannel, os.Kill) + + for { + select { + case <-interruptChannel: + slog.Info("Received interrupt signal, quitting") + systray.Quit() + case <-menuQuit.ClickedCh: + slog.Info("Requesting exit") + systray.Quit() + case newState := <-stateChannel: + if newState == "open" { + systray.SetIcon(openIcon) + } else if newState == "closed" { + systray.SetIcon(closedIcon) + } else { + slog.Warn("Unknown state", "state", newState) + systray.SetIcon(unknownIcon) + } + } + } +} + +func onExit() { + +} diff --git a/open.ico b/open.ico new file mode 100644 index 0000000000000000000000000000000000000000..618f697dd7c960542ddb542f416c33cbe482e8b3 GIT binary patch literal 7673 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 literal 0 HcmV?d00001 diff --git a/unknown.ico b/unknown.ico new file mode 100644 index 0000000000000000000000000000000000000000..dc05cdcb99ca491721b7fb7872ef9f0cba2f292d GIT binary patch literal 7011 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 literal 0 HcmV?d00001