// // rhctl // // Copyright (C) 2009-2016 Christian Pointner // // 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 . // 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" SwitchCmdAudioApplyInput SwitchCmdString = "*uiio" SwitchCmdAudioApplyInputAll 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 } type SwitchCommand struct { Cmd SwitchCmdString Args []interface{} Response chan<- interface{} } func SwitchCommandParseStatus(args []string) (cmdstr SwitchCmdString, cmdargs []interface{}, err error) { if len(args) == 0 { err = fmt.Errorf("missing argument ") return } switch args[0] { case "audio": cmdstr = SwitchCmdStatusAudio case "gpi": cmdstr = SwitchCmdStatusGPI case "oc": cmdstr = SwitchCmdStatusOC case "relay": cmdstr = SwitchCmdStatusRelay case "silence": cmdstr = SwitchCmdStatusSilence default: err = fmt.Errorf("unknown status-type: '%s'", args[0]) return } return } func SwitchCommandParseAudio(args []string) (cmdstr SwitchCmdString, cmdargs []interface{}, err error) { if len(args) < 2 || len(args) > 3 { err = fmt.Errorf("wrong number of arguments") return } var onum SwitchOutputNum if args[0] != "all" { if err = onum.FromString(args[0]); err != nil { return } cmdargs = append(cmdargs, onum) } var inum SwitchInputNum if len(args) == 3 { if err = inum.FromString(args[2]); err != nil { return } cmdargs = append(cmdargs, inum) } switch args[1] { case "apply": if len(args) != 3 { err = fmt.Errorf("wrong number of arguments") return } if onum == 0 { cmdstr = SwitchCmdAudioApplyInputAll } else { cmdstr = SwitchCmdAudioApplyInput } case "add": if len(args) != 3 { err = fmt.Errorf("wrong number of arguments") return } switch onum { case 1: cmdstr = SwitchCmdAudioAddInputTo1 case 2: cmdstr = SwitchCmdAudioAddInputTo2 default: err = fmt.Errorf("this operation cannot be applied to all outputs") return } case "remove": if len(args) != 3 { err = fmt.Errorf("wrong number of arguments") return } switch onum { case 1: cmdstr = SwitchCmdAudioRemoveInputFrom1 case 2: cmdstr = SwitchCmdAudioRemoveInputFrom2 default: err = fmt.Errorf("this operation cannot be applied to all outputs") return } case "up": if len(args) != 3 { err = fmt.Errorf("wrong number of arguments") return } if onum != 1 { err = fmt.Errorf("this operation is only allowed on output 1") return } cmdstr = SwitchCmdAudioFadeUpInput case "down": if len(args) != 3 { err = fmt.Errorf("wrong number of arguments") return } if onum != 1 { err = fmt.Errorf("this operation is only allowed on output 1") return } cmdstr = SwitchCmdAudioFadeDownInput case "mute": if len(args) == 3 { if onum == 0 { cmdstr = SwitchCmdAudioMuteInputAll } else { cmdstr = SwitchCmdAudioMuteInput } } else { if onum == 0 { cmdstr = SwitchCmdAudioMuteOutputAll } else { cmdstr = SwitchCmdAudioMuteOutput } } default: err = fmt.Errorf("unknown operation: '%s', must be one of latch, unlatch, pulse", args[1]) return } return } func SwitchCommandParseRelay(args []string) (cmdstr SwitchCmdString, cmdargs []interface{}, err error) { if len(args) != 2 { err = fmt.Errorf("wrong number of arguments, expecting: (latch|unlatch|pulse)") return } var num SwitchRelayNum if err = num.FromString(args[0]); err != nil { return } cmdargs = append(cmdargs, num) switch args[1] { case "latch": cmdstr = SwitchCmdRelayLatch case "unlatch": cmdstr = SwitchCmdRelayUnlatch case "pulse": cmdstr = SwitchCmdRelayPulse default: err = fmt.Errorf("unknown operation: '%s', must be one of latch, unlatch, pulse", args[1]) return } return } func SwitchCommandParseOC(args []string) (cmdstr SwitchCmdString, cmdargs []interface{}, err error) { if len(args) != 2 { err = fmt.Errorf("wrong number of arguments, expecting: (latch|unlatch|pulse)") return } var num SwitchOCNum if err = num.FromString(args[0]); err != nil { return } cmdargs = append(cmdargs, num) switch args[1] { case "latch": cmdstr = SwitchCmdOCLatch case "unlatch": cmdstr = SwitchCmdOCUnlatch case "pulse": cmdstr = SwitchCmdOCPulse default: err = fmt.Errorf("unknown operation: '%s', must be one of latch, unlatch, pulse", args[1]) return } return } func NewSwitchCommandFromStrings(cmd string, args ...string) (c *SwitchCommand, err error) { c = &SwitchCommand{} switch cmd { case "status": c.Cmd, c.Args, err = SwitchCommandParseStatus(args) case "out": c.Cmd, c.Args, err = SwitchCommandParseAudio(args) case "relay": c.Cmd, c.Args, err = SwitchCommandParseRelay(args) case "oc": c.Cmd, c.Args, err = SwitchCommandParseOC(args) default: return nil, fmt.Errorf("unknown command '%s'", cmd) } return }