From c786af33222f637bedc6409a49f7e7bfe591052d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Hilligs=C3=B8e?= Date: Wed, 19 Apr 2023 08:37:01 +0200 Subject: [PATCH] Initial test and some setup --- LICENSE | 21 +++++++ README.md | 35 +++++++++++ examples/get_info/get_info.go | 23 ++++++++ go.mod | 3 + kefw2/kefw2.go | 56 ++++++++++++++++++ research/commands.http | 108 ++++++++++++++++++++++++++++++++++ 6 files changed, 246 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 examples/get_info/get_info.go create mode 100644 go.mod create mode 100644 kefw2/kefw2.go create mode 100644 research/commands.http diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3948ae9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Jens Hilligsøe, github.com/hilli + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..ce86043 --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +# go-kef-w2 + +Library for controlling KEFs W2 platform based speakers over the network. + +## Usage + +```go +package main + +import ( + "fmt" + "log" + + "github.com/hilli/go-kef-w2/kefw2" +) + +func main() { + speaker, err := kef.NewSpeaker("10.0.0.93") + if err != nil { + log.Fatal(err) + } + + fmt.Println(speaker.Name) + fmt.Println(speaker.Model) + fmt.Println(speaker.MacAddress) + fmt.Println(speaker.IPAddress) + fmt.Println(speaker.Version) + fmt.Println(speaker.SerialNumber) + fmt.Println(speaker.MacAddress) +} +``` + +## License + +MIT License diff --git a/examples/get_info/get_info.go b/examples/get_info/get_info.go new file mode 100644 index 0000000..eeef7cb --- /dev/null +++ b/examples/get_info/get_info.go @@ -0,0 +1,23 @@ +package main + +import ( + "fmt" + "log" + + "github.com/hilli/go-kef-w2/kefw2" +) + +func main() { + speaker, err := kefw2.NewSpeaker("10.0.0.93") + if err != nil { + log.Fatal(err) + } + + fmt.Println(speaker.Name) + fmt.Println(speaker.Model) + fmt.Println(speaker.MacAddress) + fmt.Println(speaker.IPAddress) + fmt.Println(speaker.Version) + fmt.Println(speaker.SerialNumber) + fmt.Println(speaker.MacAddress) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..2eddf50 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/hilli/go-kef-w2 + +go 1.20 diff --git a/kefw2/kefw2.go b/kefw2/kefw2.go new file mode 100644 index 0000000..2495e88 --- /dev/null +++ b/kefw2/kefw2.go @@ -0,0 +1,56 @@ +package kefw2 + +import ( + "fmt" + "time" +) + +type KEFSpeaker struct { + KEFSpeakerIP string + Name string + Model string + MacAddress string + IPAddress string + Version string + SerialNumber string + pollingQueue string + lastPollTime time.Time +} + +func NewSpeaker(KEFSpeakerIP string) (KEFSpeaker, error) { + if KEFSpeakerIP == "" { + return KEFSpeaker{}, fmt.Errorf("KEF Speaker IP is empty") + } + return KEFSpeaker{ + KEFSpeakerIP: KEFSpeakerIP, + }, nil +} + +func (s KEFSpeaker) UpdateInfo() (error) { + return nil +} + +func (s KEFSpeaker) SetVolume(volume int) (error) { + return nil +} + +func (s KEFSpeaker) Mute() (error) { + return nil +} + +func (s KEFSpeaker) Unmute() (error) { + return nil +} + +func (s KEFSpeaker) PowerOn(power bool) (error) { + return nil +} + +func (s KEFSpeaker) PowerOff(power bool) (error) { + return nil +} + +func (s KEFSpeaker) SetSource(source string) (error) { + return nil +} + diff --git a/research/commands.http b/research/commands.http new file mode 100644 index 0000000..d94392b --- /dev/null +++ b/research/commands.http @@ -0,0 +1,108 @@ +VS Code REST Client + +# KEF LS60 Wireless base URL +@baseurl = http://10.0.0.93 + +### Get Poll Queue +GET {{baseurl}}/api/event/pollQueue +Accept: application/json +Content-Type: application/json + + +### Get MAC Address +POST {{baseurl}}/api/getData +Accept: application/json +Content-Type: application/json + +{"path": "settings:/system/primaryMacAddress", "roles": "value"} + +### Get Device Name +POST {{baseurl}}/api/getData +Accept: application/json +Content-Type: application/json + +{"path": "settings:/deviceName", "roles": "value"} + + +### Get Device Status +# Possible Statuses are: +# standby or powerOn +POST {{baseurl}}/api/getData +Accept: application/json +Content-Type: application/json + +{"path": "settings:/kef/host/speakerStatus", "roles": "value"} + +### Get Device Source +# Possible Sources are: +# standby (not powered on), wifi, bluetooth, tv, optic, coaxial or analog (aux in KEF Control) +POST {{baseurl}}/api/getData +Accept: application/json +Content-Type: application/json + +{"path": "settings:/kef/play/physicalSource", "roles": "value"} + +### Set Device Source +# Possible Sources are: +# standby (not powered on), wifi, bluetooth, tv, optic, coaxial or analog (aux in KEF Control) +POST {{baseurl}}/api/setData +Accept: application/json +Content-Type: application/json + +{ + "path": "settings:/kef/play/physicalSource", + "roles": "value", + "value": { + "type": "kefPhysicalSource", + "kefPhysicalSource": "wifi" + } +} + +### Get Volume +POST {{baseurl}}/api/getData +Accept: application/json +Content-Type: application/json + +{ + "path": "player:volume", + "roles": "value" +} + + +### Set Volume +POST {{baseurl}}/api/setData +Accept: application/json +Content-Type: application/json + +{ + "path": "player:volume", + "roles": "value", + "value": { + "type": "i32_", + "i32_": 15 + } +} + + + + + +### Song Progress +POST {{baseurl}}/api/getData +Accept: application/json +Content-Type: application/json + +{ + "path": "player:player/data/playTime", + "roles": "value" +} + +### Player data (large object) +POST {{baseurl}}/api/getData +Accept: application/json +Content-Type: application/json + +{ + "path": "player:player/data", + "roles": "value" +} \ No newline at end of file