soundtouch

package module
v0.0.0-...-54a0151 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 2, 2024 License: MIT Imports: 13 Imported by: 9

README

Golang Soundtouch API

Base on Nodejs version

Sample

package main

import (
  "log"

  "github.com/llun/soundtouch-golang"
)

func main() {
  speakerCh := make(chan *soundtouch.Speaker, 1)
  soundtouch.Lookup(speakerCh)
  speaker := <-speakerCh

  websocketCh, err := speaker.Listen()
  if err != nil {
    log.Fatal(err)
  }

  data, err := speaker.Volume()
  if err != nil {
    log.Fatal(err)
  }
  log.Printf("%v\n", data)
  log.Printf("%s\n", data.Raw)

  speaker.SetVolume(40)
  log.Printf("Set volume to 40")

  for message := range websocketCh {
    log.Printf(message)
  }
}

License

MIT

Documentation

Index

Constants

View Source
const (
	PlayState         = "PLAY_STATE"
	PauseState        = "PAUSE_STATE"
	BufferingState    = "BUFFERING_STATE"
	InvalidPlayStatus = "INVALID_PLAY_STATUS"
	StopState         = "STOP"
	Standby           = "STANDBY"
)

All Playing states of soundtouch speaker

View Source
const (
	Slave              = "SLAVE_SOURCE"
	InternetRadio      = "INTERNET_RADIO"
	LocalInternetRadio = "LOCAL_INTERNET_RADIO"
	Pandora            = "PANDORA"
	TuneIn             = "TUNEIN"
	Airplay            = "AIRPLAY"
	StoredMusic        = "STORED_MUSIC"
	Aux                = "AUX"
	Bluetooth          = "BLUETOOTH"
	Product            = "PRODUCT"
	OffSource          = "OFF_SOURCE"
	CurratedRadio      = "CURRATED_RADIO"
	UPDATE             = "UPDATE"
	Deezer             = "DEEZER"
	Spotify            = "SPOTIFY"
	Alexa              = "ALEXA"
	IHeart             = "IHEART"
)

All Sources of a soundtouch speaker

View Source
const (
	RadioStreaming = "RADIO_STREAMING"
	TrackOnDemand  = "TRACK_ONDEMAND"
	RadioTracks    = "RADIO_TRACKS" // like Alexa
)

All StreamTypes

View Source
const (
	// PRESS KEY Values
	PLAY           = "PLAY"
	PAUSE          = "PAUSE"
	PLAYPAUSE      = "PLAY_PAUSE"
	PREVTRACK      = "PREV_TRACK"
	NEXTTRACK      = "NEXT_TRACK"
	MUTE           = "MUTE"
	SHUFFLEON      = "SHUFFLE_ON"
	SHUFFLEOFF     = "SHUFFLE_OFF"
	REPEATONE      = "REPEAT_ONE"
	REPEATALL      = "REPEAT_ALL"
	REPEATOFF      = "REPEAT_OFF"
	ADDFAVORITE    = "ADD_FAVORITE"
	REMOVEFAVORITE = "REMOVE_FAVORITE"
	THUMBSUP       = "THUMBS_UP"
	THUMBSDOWN     = "THUMBS_DOWN"
	BOOKMARK       = "BOOKMARK"
	// PRESS or RELEASE Values
	PRESET1 = "PRESET_1"
	PRESET2 = "PRESET_2"
	PRESET3 = "PRESET_3"
	PRESET4 = "PRESET_4"
	PRESET5 = "PRESET_5"
	PRESET6 = "PRESET_6"
	// PRESS and RELEASE Values
	POWER = "POWER"
)

All soundtouch key constants according: http://developer.bose.com/guides/bose-soundtouch-api/bose-soundtouch-api-reference

View Source
const (
	WIFI = "NETWORK_WIFI_CONNECTED"
)

All network connection types

Variables

ALLKEYS contains all KEY constant that can be sent to soundtouch

ALLSOURCES contains all soundtouch sources

ALLSTATES contains all soundtouch state constants

ALLSTREAMS contains all soundtouch streamtypes

Functions

func DumpZones

func DumpZones(log *log.Entry, s Speaker)

func GetDevices

func GetDevices(conf NetworkConfig) (speakers chan *Speaker)

GetDevices starts listening on the indicated interface for the speakers to listen for. passes to speakers the series of speakers that are handled for further processing. Closes the speaker channel after all speakers found.

func LookupSpeakers

func LookupSpeakers(iface *net.Interface) <-chan *Speaker

LookupSpeakers listens via mdns for soundtouch speakers and returns Speaker channel

func LookupStaticSpeakers

func LookupStaticSpeakers(speakerIPs []string) <-chan *Speaker

LookupSpeakers listens via mdns for soundtouch speakers and returns Speaker channel

func OpenInterface

func OpenInterface(interfaceName string) *net.Interface

OpenInterface

func SearchDevices

func SearchDevices(conf NetworkConfig) (speakers chan *Speaker)

SearchDevices searches on the indicated interface for the speakers to listen for. passes to speakers the series of speakers that are handled for further processing. Keeps the speaker channel open for additional speakers.

Types

type Component

type Component struct {
	ComponentCategory string `xml:"componentCategory" json:",omitempty"`
	SoftwareVersion   string `xml:"softwareVersion" json:",omitempty"`
	SerialNumber      string `xml:"serialNumber" json:",omitempty"`
}

Component contains some component information

type ConnectionStateUpdated

type ConnectionStateUpdated struct {
	// state="NETWORK_WIFI_CONNECTED" up="true" signal="MARGINAL_SIGNAL"
	State  string `xml:"state,attr"`
	Up     string `xml:"up,attr"`
	Signal string `xml:"signal,attr"`
}

ConnectionStateUpdated defines the message communicated with the soundtouch system

func (ConnectionStateUpdated) String

func (c ConnectionStateUpdated) String() string

String readable representation of message

type ContentItem

type ContentItem struct {
	Type         string `xml:"type,attr" json:",omitempty"`
	Source       Source `xml:"source,attr" json:",omitempty"`
	Location     string `xml:"location,attr" json:",omitempty"`
	Name         string `xml:"itemName" json:",omitempty"`
	IsPresetable bool   `xml:"isPresetable,attr"`
}

ContentItem describe a playable item

type InfluxDB

type InfluxDB struct {
	BaseHTTPURL url.URL
	Database    string
}

InfluxDB configures access to the influxdb instance

func (*InfluxDB) SetData

func (i *InfluxDB) SetData(action string, input []byte) ([]byte, error)

SetData sends POST request to the database

func (*InfluxDB) WriteURL

func (i *InfluxDB) WriteURL(action string) string

WriteURL constructs the full URL including and up until database in the form http://influx/write?db=mydata

type Info

type Info struct {
	DeviceID    string      `xml:"deviceID,attr" json:",omitempty"`
	Name        string      `xml:"name" json:",omitempty"`
	Type        string      `xml:"type" json:",omitempty"`
	IPAddress   []string    `xml:"networkInfo>ipAddress"`
	Component   []Component `xml:"components>component" json:",omitempty"`
	MargeUrl    string      `xml:"margeURL" json:",omitempty"`
	ModuleType  string      `xml:"moduleType" json:",omitempty"`
	Variant     string      `xml:"variant" json:",omitempty"`
	VariantMode string      `xml:"variantMode" json:",omitempty"`
	CountryCode string      `xml:"countryCode" json:",omitempty"`
	RegionCode  string      `xml:"regionCode" json:",omitempty"`
	Raw         []byte      `json:"-"`
}

Info defines the Info command for the soundtouch system

func (Info) String

func (s Info) String() string

String creates, depending of the loglevel different string representations on info message

type Initializer

type Initializer interface {
	// Init performs one time setup of the plugin and returns an error if the
	// configuration is invalid.
	Init() error
}

Initializer is an interface that all plugin can optionally implement to initialize the plugin.

type Key

type Key string

Key typing

type Member

type Member struct {
	IPAddress  string `xml:"ipaddress,attr"`
	MacAddress string `xml:",chardata"`
}

type MultiRoomZone

type MultiRoomZone struct {
	XMLName         xml.Name `xml:"zone"`
	Members         []Member `xml:"member"`
	Master          string   `xml:"master,attr"`
	SenderIPAddress string   `xml:"senderIPAddress,attr"`
}

MultiRoomZone defines a zone with members

func NewZone

func NewZone(master, slave Speaker) MultiRoomZone

type NetworkConfig

type NetworkConfig struct {
	InterfaceName      string
	NoOfSystems        int
	SpeakerToListenFor []string
	StaticIPAddresses  []string
	Plugins            []Plugin
}

NetworkConfig describes the soundtouch network InterfaceName as the network interface to listen, e.g. "en0" NoOfSystems is the number of expected systems. Searching for at least this amount of systems SpeakerToListenFor contains the defined list of speakers we are handling Plugins the list of handlers of handlers to be used.

type NowPlaying

type NowPlaying struct {
	PlayStatus    PlayStatus  `xml:"playStatus" json:",omitempty"`
	Source        string      `xml:"source,attr" json:",omitempty"`
	SourceAccount string      `xml:"sourceAccount,attr" json:",omitempty"`
	DeviceID      string      `xml:"deviceID,attr" json:",omitempty"`
	Content       ContentItem `xml:"ContentItem" json:",omitempty"`
	Track         string      `xml:"track" json:",omitempty"`
	Artist        string      `xml:"artist" json:",omitempty"`
	Album         string      `xml:"album" json:",omitempty"`
	TrackID       string      `xml:"trackID" json:",omitempty"`
	Art           string      `xml:"art" json:",omitempty"`
	StreamType    string      `xml:"streamType" json:",omitempty"`
	Raw           []byte      `json:"-"`
}

NowPlaying defines the now_playing message to/from soundtouch system

type PlayStatus

type PlayStatus string

PlayStatus is a string type

type Plugin

type Plugin interface {
	// SampleConfig returns the default configuration of the Input
	SampleConfig() string

	// Description returns a one-sentence description on the Input
	Description() string

	// Execute operates on one update message
	Execute(pluginName string, update Update, speaker Speaker)

	// Disable temporarely the execution of the plugin
	Disable()

	// Enable temporarely the execution of the plugin
	Enable()

	// Name returns the name of the plugin
	Name() string

	// Terminate indicates that no further plugin will be executed on this speaker
	Terminate() bool

	// IsEnabled returns true if the plugin is not suspened
	IsEnabled() bool
}

Plugin interface for that can handle valid update params

type PluginConfig

type PluginConfig struct {
	Name      string
	Speakers  []string
	Suspended bool
	Pfunction PluginFunc
}

PluginConfig describes an Plugin. It has a Name to be able to remove again Speakers list of SpeakerNames the handler is added. All if empty Terminate indicates whether this is the last handler to be called Suspended indicates that the plugin is temporarely suspended Plugin the plugin function

type PluginFunc

type PluginFunc func(pluginName string, update Update, speaker Speaker)

PluginFunc turns a function with the right signature into a update handler

func (PluginFunc) Execute

func (fn PluginFunc) Execute(pluginName string, update Update, speaker Speaker)

Execute executing the request and returning a response

type Preset

type Preset struct {
	ID      int         `xml:"id,attr"`
	Content ContentItem `xml:"ContentItem"`
}

Preset specifies a preset field in soundtouch messages

type Presets

type Presets struct {
	DeviceID string   `xml:"deviceID,attr" json:",omitempty"`
	Presets  []Preset `xml:"preset"`
	Raw      []byte   `json:"-"`
}

Presets specifies the Presets Update message

type Source

type Source string

Source is a string type

type SourceItem

type SourceItem struct {
	Source        Source `xml:"source,attr" json:",omitempty"`
	SourceAccount string `xml:"sourceAccount,attr" json:",omitempty"`
	Status        string `xml:"status,attr" json:",omitempty"`
	Local         bool   `xml:"isLocal,attr" json:",omitempty"`
	Value         string `xml:",innerxml" json:",omitempty"`
}

SourceItem defines a source within a soundtouch system

type Sources

type Sources struct {
	DeviceID    string       `xml:"deviceID,attr" json:",omitempty"`
	SourceItems []SourceItem `xml:"sourceItem"`
	Raw         []byte       `json:"-"`
}

Sources defines the soundtouch sources command

type Speaker

type Speaker struct {
	IP           net.IP
	Port         int
	BaseHTTPURL  url.URL
	WebSocketURL url.URL
	DeviceInfo   Info

	WebSocketCh chan *Update
	Plugins     []Plugin
	// contains filtered or unexported fields
}

Speaker defines a soundtouch speaker

func GetSpeaker

func GetSpeaker(updateMsg Update) *Speaker

GetSpeaker returns the Speaker instance the Update has been send from

func GetSpeakerByDeviceId

func GetSpeakerByDeviceId(deviceId string) *Speaker

GetSpeakerByDeviceId retuns a speaker for a given DeviceId

func GetSpeakerByName

func GetSpeakerByName(speakerName string) *Speaker

GetSpeakerByName retuns a speaker for a given name

func NewIPSpeaker

func NewIPSpeaker(ipAddress string) *Speaker

NewIPSpeaker creates a new speaker for the given ipAdress

func NewMdnsSpeaker

func NewMdnsSpeaker(entry *mdns.ServiceEntry) *Speaker

NewMdnsSpeaker returns a new Speaker entity based on a mdns service entry

func (*Speaker) AddPlugin

func (s *Speaker) AddPlugin(uhc Plugin)

func (*Speaker) AddZoneSlave

func (s *Speaker) AddZoneSlave(zi MultiRoomZone) error

AddZoneSlave sends the addZoneSlave command to the soundtouch system To be send to the master and should contain only new speakers to add

func (*Speaker) Close

func (s *Speaker) Close() error

Close closes the socket to the soundtouch speaker

func (*Speaker) DeviceID

func (s *Speaker) DeviceID() (name string)

DeviceID returns the speakers DeviceID as indicated in the info message, or "" if name unknwon

func (*Speaker) Disable

func (s *Speaker) Disable(pluginName string)

func (*Speaker) Execute

func (s *Speaker) Execute(msgChan chan *Update)

func (*Speaker) GetData

func (s *Speaker) GetData(action string) ([]byte, error)

GetData returns received raw data retrieved a GET for a given soundtouch action

func (*Speaker) GetZone

func (s *Speaker) GetZone() (Zone, error)

GetZone sends the getZone command to the soundtouch system and returns the zone

func (*Speaker) GetZoneMembers

func (s *Speaker) GetZoneMembers() []Member

GetZoneMembers returns the Members of the zone the speaker is a member

func (*Speaker) HasPlugin

func (s *Speaker) HasPlugin(name string) bool

HasPlugin returns true if speaker has an UpdateHandler named name. False otherwise

func (*Speaker) HasZone

func (s *Speaker) HasZone() bool

HasZone returns true if the speaker has a zone

func (*Speaker) Info

func (s *Speaker) Info() (Info, error)

Info retrieves speaker information and updates the speakers info field

func (*Speaker) IsAlive

func (s *Speaker) IsAlive() bool

IsAlive returns true in case the soundtouch system is in PlayState

func (*Speaker) IsMaster

func (s *Speaker) IsMaster() bool

IsMaster returns true if the speaker is the master of a zone

func (*Speaker) IsPoweredOn

func (s *Speaker) IsPoweredOn() bool

IsPoweredOn returns true in case the soundtouch system is not in standby but powered

func (*Speaker) IsSpeakerMember

func (s *Speaker) IsSpeakerMember(members []Member) bool

func (*Speaker) Listen

func (s *Speaker) Listen() (chan *Update, error)

Listen creates a listenes that distributes Update messages via channel

func (*Speaker) Name

func (s *Speaker) Name() (name string)

Name returns the speakers name as indicated in the info message, or "" if name unknwon

func (*Speaker) NowPlaying

func (s *Speaker) NowPlaying() (NowPlaying, error)

NowPlaying sends the now_playing command to the soundtouch system

func (*Speaker) PowerOff

func (s *Speaker) PowerOff() bool

PowerOff powers off the soundtouch systems. True on success. Returns false in case it was already powered off.

func (*Speaker) PowerOn

func (s *Speaker) PowerOn() bool

PowerOn switches the soundtouch system on. True on success. Returns false in case the system was already powered

func (*Speaker) PowerOnWithVolume

func (s *Speaker) PowerOnWithVolume(vol int) bool

PowerOnWithVolume switches the soundtouch system on and set's a specific volume. True on success. Returns false in case the system was already powered with no volume set.

func (*Speaker) Presets

func (s *Speaker) Presets() (Presets, error)

Presets queries the presets of a soundtouch system

func (*Speaker) PressKey

func (s *Speaker) PressKey(key Key) error

PressKey sends key press command to soundtouch system. For POWER also release is send immediatly afterwards.

func (*Speaker) RemovePlugin

func (s *Speaker) RemovePlugin(name string)

func (*Speaker) Select

func (s *Speaker) Select(item ContentItem) error

Select sends the select command to the soundtouch system

func (*Speaker) SetData

func (s *Speaker) SetData(action string, input []byte) ([]byte, error)

SetData sets raw data via POST for a given soundtouch action

func (*Speaker) SetVolume

func (s *Speaker) SetVolume(volume int) error

SetVolume sends the volume command to the soundtouch system to set the volume

func (*Speaker) SetZone

func (s *Speaker) SetZone(zi MultiRoomZone) error

SetZone sends the addZoneSlave command to the soundtouch system creates a multi-room zone

func (*Speaker) Sources

func (s *Speaker) Sources() (Sources, error)

Sources sends the sources command to the soundtouch system

func (*Speaker) Volume

func (s *Speaker) Volume() (Volume, error)

Volume sends the volume command to the soundtouch system to retrieve the volume

type Speakers

type Speakers map[string]*Speaker

func GetKnownDevices

func GetKnownDevices() Speakers

GetKnownDevices returns a map of the already seen speakers

type Update

type Update struct {
	DeviceID string
	Value    interface{}
}

Update carries all update messages communicated to/from soundtouch system

func NewUpdate

func NewUpdate(body []byte) (*Update, error)

NewUpdate returns an Update decoded from a received message

func (Update) Album

func (u Update) Album() string

Album returns the Album if present, else empty

func (Update) Artist

func (u Update) Artist() string

Artist returns the artist if present, empty else

func (Update) ContentItem

func (u Update) ContentItem() ContentItem

ContentItem returns the ContentItem if present, or an empty one if not present

func (Update) HasContentItem

func (u Update) HasContentItem() bool

HasContentItem returns true if the Update message has contentItem, false else

func (Update) Is

func (u Update) Is(msgTypeName string) bool

Is returns true in case Update message is of type msgTypeName is one of - ConnectionStateUpdated - Volume - NowPlaying - Preset

func (*Update) Lineproto

func (u *Update) Lineproto(i InfluxDB, message *Update) (string, error)

Lineproto returns a lineproto encoding of the Update message

func (Update) String

func (u Update) String() string

String returns the specific part of an update message

type Volume

type Volume struct {
	DeviceID     string `xml:"deviceID,attr"`
	TargetVolume int    `xml:"targetvolume"`
	ActualVolume int    `xml:"actualvolume"`
	Muted        bool   `xml:"mutedenabled"`
	Raw          []byte `json:"-"`
}

Volume defines the Volume command

type Zone

type Zone struct {
	Members         []Member `xml:"member"`
	SenderIPAddress string   `xml:"senderIPAddress,attr"`
	SenderIsMaster  bool     `xml:"senderIsMaster,attr"`
	Master          string   `xml:"master,attr"`
	Raw             string   `xml:"-"`
}

Zone defines the zone message to/from soundtouch system

func (*Zone) AddSlave

func (z *Zone) AddSlave(s Speaker)

AddSlave adds a speaker to an existing zone

type ZoneSlave

type ZoneSlave struct {
	XMLName xml.Name `xml:"zone"`
	Members []Member `xml:"member"`
	Master  string   `xml:"master,attr"`
}

ZoneSlave defines a zone slave

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL