Skip to content

Commit

Permalink
Cleanup and tuning
Browse files Browse the repository at this point in the history
  • Loading branch information
abates committed Apr 13, 2019
1 parent ecb7a09 commit c9ce00d
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 52 deletions.
70 changes: 34 additions & 36 deletions cmd/ic/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,28 +27,30 @@ import (
"github.com/abates/insteon/plm"
)

var device insteon.Device
var addr insteon.Address
type device struct {
insteon.Device
addr insteon.Address
}

func init() {
cmd := app.SubCommand("device", cli.UsageOption("<device id> <command>"), cli.DescOption("Interact with a specific device"), cli.CallbackOption(devCmd))
cmd.Arguments.Var(&addr, "<device id>")
cmd.SubCommand("info", cli.DescOption("retrieve device info"), cli.CallbackOption(devInfoCmd))
cmd.SubCommand("link", cli.DescOption("enter linking mode"), cli.CallbackOption(devLinkCmd))
cmd.SubCommand("unlink", cli.DescOption("enter unlinking mode"), cli.CallbackOption(devUnlinkCmd))
cmd.SubCommand("exitlink", cli.DescOption("exit linking mode"), cli.CallbackOption(devExitLinkCmd))
cmd.SubCommand("cleanup", cli.DescOption("remove duplicate links in the all-link database"), cli.CallbackOption(devCleanupCmd))
cmd.SubCommand("dump", cli.DescOption("dump the device all-link database"), cli.CallbackOption(devDumpCmd))
cmd.SubCommand("edit", cli.DescOption("edit the device all-link database"), cli.CallbackOption(devEditCmd))
cmd.SubCommand("version", cli.UsageOption("<device id>"), cli.DescOption("Retrieve the Insteon engine version"), cli.CallbackOption(devVersionCmd))
d := &device{}
cmd := app.SubCommand("device", cli.UsageOption("<device id> <command>"), cli.DescOption("Interact with a specific device"), cli.CallbackOption(d.init))
cmd.Arguments.Var(&d.addr, "<device id>")
cmd.SubCommand("info", cli.DescOption("retrieve device info"), cli.CallbackOption(d.infoCmd))
cmd.SubCommand("link", cli.DescOption("enter linking mode"), cli.CallbackOption(d.linkCmd))
cmd.SubCommand("unlink", cli.DescOption("enter unlinking mode"), cli.CallbackOption(d.unlinkCmd))
cmd.SubCommand("exitlink", cli.DescOption("exit linking mode"), cli.CallbackOption(d.exitLinkCmd))
cmd.SubCommand("dump", cli.DescOption("dump the device all-link database"), cli.CallbackOption(d.dumpCmd))
cmd.SubCommand("edit", cli.DescOption("edit the device all-link database"), cli.CallbackOption(d.editCmd))
cmd.SubCommand("version", cli.UsageOption("<device id>"), cli.DescOption("Retrieve the Insteon engine version"), cli.CallbackOption(d.versionCmd))
}

func devCmd() (err error) {
device, err = devConnect(modem, addr)
func (dev *device) init() (err error) {
dev.Device, err = connect(modem, dev.addr)
return err
}

func devConnect(plm *plm.PLM, addr insteon.Address) (insteon.Device, error) {
func connect(plm *plm.PLM, addr insteon.Address) (insteon.Device, error) {
device, err := plm.Open(addr)
if err == insteon.ErrNotLinked {
msg := fmt.Sprintf("Device %s is not linked to the PLM. Link now? (y/n) ", addr)
Expand All @@ -58,46 +60,46 @@ func devConnect(plm *plm.PLM, addr insteon.Address) (insteon.Device, error) {
}

if err == nil {
device, err = plm.Open(addr)
device, err = plm.Open(addr, insteon.ConnectionTimeout(timeoutFlag), insteon.ConnectionTTL(uint8(ttlFlag)))
}
}
return device, err
}

func devLink(cb func(linkable insteon.LinkableDevice) error) error {
func devLink(device insteon.Device, cb func(dev insteon.LinkableDevice) error) error {
if linkable, ok := device.(insteon.LinkableDevice); ok {
return cb(linkable)
}
return fmt.Errorf("%v is not a linkable device", device)
}

func devLinkCmd() error {
return devLink(func(linkable insteon.LinkableDevice) error {
func (dev *device) linkCmd() error {
return devLink(dev, func(linkable insteon.LinkableDevice) error {
return linkable.EnterLinkingMode(insteon.Group(0x01))
})
}

func devUnlinkCmd() error {
return devLink(func(linkable insteon.LinkableDevice) error {
func (dev *device) unlinkCmd() error {
return devLink(dev, func(linkable insteon.LinkableDevice) error {
return linkable.EnterUnlinkingMode(insteon.Group(0x01))
})
}

func devExitLinkCmd() error {
return devLink(func(linkable insteon.LinkableDevice) error {
func (dev *device) exitLinkCmd() error {
return devLink(dev, func(linkable insteon.LinkableDevice) error {
return linkable.ExitLinkingMode()
})
}

func devDumpCmd() error {
return devLink(func(linkable insteon.LinkableDevice) error {
func (dev *device) dumpCmd() error {
return devLink(dev, func(linkable insteon.LinkableDevice) error {
err := dumpLinkDatabase(linkable)
return err
})
}

func devInfoCmd() (err error) {
return printDevInfo(device, "")
func (dev *device) infoCmd() (err error) {
return printDevInfo(dev.Device, "")
}

func printDevInfo(device insteon.Device, extra string) (err error) {
Expand All @@ -112,23 +114,23 @@ func printDevInfo(device insteon.Device, extra string) (err error) {
fmt.Printf("%s\n", extra)
}

err = devLink(func(linkable insteon.LinkableDevice) error {
err = devLink(device, func(linkable insteon.LinkableDevice) error {
return link.PrintLinks(os.Stdout, linkable)
})
}
return err
}

func devVersionCmd() error {
firmware, _, err := device.IDRequest()
func (dev *device) versionCmd() error {
firmware, _, err := dev.IDRequest()
if err == nil {
fmt.Printf("Device version: %s\n", firmware)
}
return err
}

func devEditCmd() error {
return devLink(func(linkable insteon.LinkableDevice) error {
func (dev *device) editCmd() error {
return devLink(dev, func(linkable insteon.LinkableDevice) error {
dbLinks, _ := linkable.Links()
if len(dbLinks) == 0 {
return fmt.Errorf("No links to edit")
Expand Down Expand Up @@ -206,7 +208,3 @@ func devEditCmd() error {
return err
})
}

func devCleanupCmd() error {
return nil
}
4 changes: 2 additions & 2 deletions cmd/ic/dimmer.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@ func init() {
}

func (dim *dimmer) init() (err error) {
device, err := devConnect(modem, addr)
device, err := connect(modem, dim.addr)
if err == nil {
if d, ok := device.(insteon.Dimmer); ok {
dim.Dimmer = d
} else {
err = fmt.Errorf("Device %s is not a dimmer", addr)
err = fmt.Errorf("Device %s is not a dimmer", dim.addr)
}
}
return err
Expand Down
8 changes: 3 additions & 5 deletions cmd/ic/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ var (
serialPortFlag string
timeoutFlag time.Duration
writeDelayFlag time.Duration

app = cli.New(os.Args[0], cli.CallbackOption(run))
ttlFlag uint
app = cli.New(os.Args[0], cli.CallbackOption(run))
)

func init() {
Expand All @@ -41,6 +41,7 @@ func init() {
app.Flags.Var(&logLevelFlag, "log", "Log Level {none|info|debug|trace}")
app.Flags.DurationVar(&timeoutFlag, "timeout", 3*time.Second, "read/write timeout duration")
app.Flags.DurationVar(&writeDelayFlag, "writeDelay", 500*time.Millisecond, "writeDelay duration")
app.Flags.UintVar(&ttlFlag, "ttl", 3, "default ttl for sending Insteon messages")
}

func run() error {
Expand All @@ -56,10 +57,7 @@ func run() error {
s, err := serial.OpenPort(c)

if err == nil {
defer s.Close()

modem = plm.New(plm.NewPort(s, timeoutFlag), timeoutFlag, plm.WriteDelay(writeDelayFlag))
defer modem.Close()
}
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/ic/plm.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type addrList []insteon.Address

func (al *addrList) Set(str string) error {
for _, v := range strings.Split(str, ",") {
addr = insteon.Address{}
addr := insteon.Address{}
err := addr.Set(v)
if err != nil {
return err
Expand Down
8 changes: 4 additions & 4 deletions cmd/ic/switch.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ func init() {
cmd.Arguments.Bool(&sw.led, "<true|false>")
}

func (sw *swtch) init() (err error) {
device, err = devConnect(modem, addr)
func (sw *swtch) init() error {
device, err := connect(modem, sw.addr)
if err == nil {
if s, ok := device.(insteon.Switch); ok {
sw.Switch = s
} else {
err = fmt.Errorf("Device at %s is a %T not a switch", addr, device)
err = fmt.Errorf("Device at %s is a %T not a switch", sw.addr, device)
}
}
return err
Expand All @@ -55,7 +55,7 @@ func (sw *swtch) init() (err error) {
func (sw *swtch) switchConfigCmd() error {
config, err := sw.SwitchConfig()
if err == nil {
err = printDevInfo(device, fmt.Sprintf(" X10 Address: %02x.%02x", config.HouseCode, config.UnitCode))
err = printDevInfo(sw, fmt.Sprintf(" X10 Address: %02x.%02x", config.HouseCode, config.UnitCode))
}
return err
}
Expand Down
9 changes: 9 additions & 0 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ type connection struct {
addr Address
match []Command
timeout time.Duration
ttl uint8

txCh chan<- *Message
rxCh <-chan *Message
Expand All @@ -83,6 +84,13 @@ type connection struct {
// ConnectionOption provides a means to customize the connection config
type ConnectionOption func(*connection)

// ConnectionTTL will set the connection's time to live flag
func ConnectionTTL(ttl uint8) ConnectionOption {
return func(conn *connection) {
conn.ttl = ttl
}
}

// ConnectionTimeout is a ConnectionOption that will set the connection's read
// timeout
func ConnectionTimeout(timeout time.Duration) ConnectionOption {
Expand Down Expand Up @@ -210,6 +218,7 @@ func (conn *connection) readLoop() {

func (conn *connection) Send(msg *Message) (ack *Message, err error) {
msg.Dst = conn.addr
msg.Flags = Flag(MsgTypeDirect, len(msg.Payload) > 0, conn.ttl, conn.ttl)
Log.Tracef("Connection %v TX %v", conn.addr, msg)
conn.txCh <- msg

Expand Down
1 change: 1 addition & 0 deletions connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func TestConnectionOptions(t *testing.T) {
{"Timeout Option", ConnectionTimeout(time.Hour), &connection{timeout: time.Hour}},
{"Filter Option", ConnectionFilter(CmdReadWriteALDB), &connection{match: []Command{CmdReadWriteALDB}}},
{"Mutex Option", ConnectionMutex(mu), &connection{Mutex: mu}},
{"TTL Option", ConnectionTTL(3), &connection{ttl: 3}},
}

for _, test := range tests {
Expand Down
8 changes: 4 additions & 4 deletions plm/plm.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,12 @@ func (plm *PLM) send(txPacket *Packet) (ack *Packet, err error) {
return plm.tx(txPacket)
}

func (plm *PLM) Connect(addr insteon.Address) insteon.Connection {
return insteon.NewConnection(plm.insteonTxCh, plm.insteonRxCh, addr, insteon.ConnectionTimeout(plm.timeout))
func (plm *PLM) Connect(addr insteon.Address, options ...insteon.ConnectionOption) insteon.Connection {
return insteon.NewConnection(plm.insteonTxCh, plm.insteonRxCh, addr, options...)
}

func (plm *PLM) Open(addr insteon.Address) (insteon.Device, error) {
conn := plm.Connect(addr)
func (plm *PLM) Open(addr insteon.Address, options ...insteon.ConnectionOption) (insteon.Device, error) {
conn := plm.Connect(addr, options...)
return insteon.Open(conn, plm.timeout)
}

Expand Down

0 comments on commit c9ce00d

Please sign in to comment.