From b2884f87b7a62dafabab754e1e64ea338e02d145 Mon Sep 17 00:00:00 2001
From: Christian Pointner <equinox@spreadspace.org>
Date: Wed, 30 Mar 2016 07:10:53 +0200
Subject: added generator for switch commands


diff --git a/sample-config.toml b/sample-config.toml
index af68f76..3a57bef 100644
--- a/sample-config.toml
+++ b/sample-config.toml
@@ -2,6 +2,7 @@
 dev = "/dev/ttyUSB0"
 baud = 19200
 timeout = "500ms"
+unit = 0
 ports = [ { name = "master_main", number = 1 },
           { name = "master_music", number = 2 },
           { name = "standby_main", number = 3 },
diff --git a/src/rhctl/audio_switch.go b/src/rhctl/audio_switch.go
index 764a231..2a88b0d 100644
--- a/src/rhctl/audio_switch.go
+++ b/src/rhctl/audio_switch.go
@@ -49,7 +49,7 @@ type SwitchResponse struct {
 }
 
 type SwitchCommand struct {
-	Cmd      string
+	Cmd      SwitchCmdString
 	Response chan<- SwitchResponse
 }
 
@@ -89,6 +89,7 @@ type AudioSwitch struct {
 	timeout  time.Duration
 	current  *SwitchCommand
 	timer    *time.Timer
+	unit     SwitchUnitID
 	Commands chan *SwitchCommand
 	Updates  chan SwitchUpdate
 }
@@ -158,7 +159,7 @@ func (sw *AudioSwitch) Run() {
 				return
 			case cmd := <-sw.Commands:
 				sw.current = cmd
-				sw.port.tx <- cmd.Cmd
+				sw.port.tx <- cmd.Cmd.Generate(sw.unit)
 				sw.timer = time.NewTimer(sw.timeout)
 			case data := <-sw.port.rx:
 				sw.handleData(data)
@@ -173,6 +174,7 @@ func SwitchInit(conf *Config) (sw *AudioSwitch, err error) {
 	if conf.Audioswitch.Timeout.Duration > 0 {
 		sw.timeout = conf.Audioswitch.Timeout.Duration
 	}
+	sw.unit = conf.Audioswitch.Unit
 	sw.Commands = make(chan *SwitchCommand, 8)
 	sw.Updates = make(chan SwitchUpdate, 32)
 
diff --git a/src/rhctl/audio_switch_command.go b/src/rhctl/audio_switch_command.go
new file mode 100644
index 0000000..693689c
--- /dev/null
+++ b/src/rhctl/audio_switch_command.go
@@ -0,0 +1,173 @@
+//
+//  rhctl
+//
+//  Copyright (C) 2009-2016 Christian Pointner <equinox@helsinki.at>
+//
+//  This file is part of rhctl.
+//
+//  rhctl is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  any later version.
+//
+//  rhctl is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with rhctl. If not, see <http://www.gnu.org/licenses/>.
+//
+
+package main
+
+import (
+	"fmt"
+	"strconv"
+	"strings"
+)
+
+type SwitchUnitID uint
+
+func (u SwitchUnitID) String() string {
+	return strconv.FormatUint(uint64(u), 10)
+}
+
+func (u *SwitchUnitID) FromString(str string) error {
+	vuint, err := strconv.ParseUint(str, 10, 32)
+	if err != nil {
+		return err
+	}
+	if vuint > 3 {
+		return fmt.Errorf("switch unit ID is out of range")
+	}
+	*u = SwitchUnitID(vuint)
+	return nil
+}
+
+func (u *SwitchUnitID) UnmarshalTOML(data []byte) error {
+	return u.FromString(string(data))
+}
+
+type SwitchInputNum uint
+
+func (i SwitchInputNum) String() string {
+	return strconv.FormatUint(uint64(i), 10)
+}
+
+func (i *SwitchInputNum) FromString(str string) error {
+	vuint, err := strconv.ParseUint(str, 10, 32)
+	if err != nil {
+		return err
+	}
+	if vuint < 1 || vuint > 8 {
+		return fmt.Errorf("switch input number is out of range")
+	}
+	*i = SwitchInputNum(vuint)
+	return nil
+}
+
+type SwitchOutputNum uint
+
+func (o SwitchOutputNum) String() string {
+	return strconv.FormatUint(uint64(o), 10)
+}
+
+func (o *SwitchOutputNum) FromString(str string) error {
+	vuint, err := strconv.ParseUint(str, 10, 32)
+	if err != nil {
+		return err
+	}
+	if vuint < 1 || vuint > 2 {
+		return fmt.Errorf("switch output number is out of range")
+	}
+	*o = SwitchOutputNum(vuint)
+	return nil
+}
+
+type SwitchRelayNum uint
+
+func (r SwitchRelayNum) String() string {
+	return strconv.FormatUint(uint64(r), 10)
+}
+
+func (r *SwitchRelayNum) FromString(str string) error {
+	vuint, err := strconv.ParseUint(str, 10, 32)
+	if err != nil {
+		return err
+	}
+	if vuint < 1 || vuint > 8 {
+		return fmt.Errorf("switch relay number is out of range")
+	}
+	*r = SwitchRelayNum(vuint)
+	return nil
+}
+
+type SwitchOCNum uint
+
+func (o SwitchOCNum) String() string {
+	return strconv.FormatUint(uint64(o), 10)
+}
+
+func (o *SwitchOCNum) FromString(str string) error {
+	vuint, err := strconv.ParseUint(str, 10, 32)
+	if err != nil {
+		return err
+	}
+	if vuint < 1 || vuint > 8 {
+		return fmt.Errorf("switch OC number is out of range")
+	}
+	*o = SwitchOCNum(vuint)
+	return nil
+}
+
+type SwitchCmdString string
+
+const (
+	SwitchCmdStatusAudio   SwitchCmdString = "*uSL"
+	SwitchCmdStatusGPI     SwitchCmdString = "*uSPA"
+	SwitchCmdStatusOC      SwitchCmdString = "*uSO"
+	SwitchCmdStatusRelay   SwitchCmdString = "*uSR"
+	SwitchCmdStatusSilence SwitchCmdString = "*uSS"
+
+	SwitchCmdAudioSelectInput      SwitchCmdString = "*uiio"
+	SwitchCmdAudioSelectInputAll   SwitchCmdString = "*uiiA"
+	SwitchCmdAudioAddInputTo1      SwitchCmdString = "*uii3"
+	SwitchCmdAudioAddInputTo2      SwitchCmdString = "*uii4"
+	SwitchCmdAudioRemoveInputFrom1 SwitchCmdString = "*uii5"
+	SwitchCmdAudioRemoveInputFrom2 SwitchCmdString = "*uii6"
+	SwitchCmdAudioMuteInput        SwitchCmdString = "*uiiMo"
+	SwitchCmdAudioMuteInputAll     SwitchCmdString = "*uiiMA"
+	SwitchCmdAudioMuteOutput       SwitchCmdString = "*uMo"
+	SwitchCmdAudioMuteOutputAll    SwitchCmdString = "*uMA"
+
+	SwitchCmdAudioFadeUpInput   SwitchCmdString = "*uFUii"
+	SwitchCmdAudioFadeDownInput SwitchCmdString = "*uFDii"
+
+	SwitchCmdOCUnlatch SwitchCmdString = "*uOOcF"
+	SwitchCmdOCLatch   SwitchCmdString = "*uOOcL"
+	SwitchCmdOCPulse   SwitchCmdString = "*uOOcP"
+
+	SwitchCmdRelayUnlatch SwitchCmdString = "*uORrF"
+	SwitchCmdRelayLatch   SwitchCmdString = "*uORrL"
+	SwitchCmdRelayPulse   SwitchCmdString = "*uORrP"
+)
+
+func (c SwitchCmdString) Generate(args ...interface{}) string {
+	s := string(c)
+	for _, arg := range args {
+		switch arg.(type) {
+		case SwitchUnitID:
+			s = strings.Replace(s, "u", fmt.Sprintf("%1d", arg.(SwitchUnitID)), -1)
+		case SwitchInputNum:
+			s = strings.Replace(s, "ii", fmt.Sprintf("%02d", arg.(SwitchInputNum)), -1)
+		case SwitchOutputNum:
+			s = strings.Replace(s, "o", fmt.Sprintf("%1d", arg.(SwitchOutputNum)), -1)
+		case SwitchRelayNum:
+			s = strings.Replace(s, "r", fmt.Sprintf("%1d", arg.(SwitchRelayNum)), -1)
+		case SwitchOCNum:
+			s = strings.Replace(s, "c", fmt.Sprintf("%1d", arg.(SwitchOCNum)), -1)
+		}
+	}
+	return s
+}
diff --git a/src/rhctl/conf.go b/src/rhctl/conf.go
index e740bde..b6f21ca 100644
--- a/src/rhctl/conf.go
+++ b/src/rhctl/conf.go
@@ -31,9 +31,10 @@ import (
 
 type Config struct {
 	Audioswitch struct {
-		Device   string   `toml:"dev"`
-		Baudrate Baudrate `toml:"baud"`
-		Timeout  Duration `toml:"timeout"`
+		Device   string       `toml:"dev"`
+		Baudrate Baudrate     `toml:"baud"`
+		Timeout  Duration     `toml:"timeout"`
+		Unit     SwitchUnitID `toml:"unit"`
 		Ports    []struct {
 			Name   string `toml:"name"`
 			Number uint   `toml:"number"`
-- 
cgit v0.10.2