Class: ExSYS::ManagedUSB

Inherits:
Object
  • Object
show all
Defined in:
lib/exsys/managed-usb.rb

Overview

Control a ExSYS Managed USB hub

Defined Under Namespace

Classes: Error

Instance Method Summary collapse

Constructor Details

#initialize(line, password = nil, debug: nil) ⇒ ManagedUSB

Initialize object.

Parameters:

  • line (String)

    Serial line (usually /dev/ttyU? or /dev/ttyUSB?)

  • password (String) (defaults to: nil)

    Hub password

  • debug (IO) (defaults to: nil)

    Write debug output



23
24
25
26
27
28
29
30
31
# File 'lib/exsys/managed-usb.rb', line 23

def initialize(line, password = nil, debug: nil)
    password ||= PASSWORD
    if password.size > 8
        raise ArgumentError, "password too long"
    end
    @line     = line
    @password = password.ljust(8)
    @debug    = debug
end

Instance Method Details

#commitObject

Save the port states to the flash memory



159
160
161
# File 'lib/exsys/managed-usb.rb', line 159

def commit
    action('WP', @password).then { self }
end

#get(type = :ports) ⇒ Object

Get hub current state for all ports

Return value depend of the asked type (default: ports)

  • ports : { 1 => true, 2 => false, …}

  • on_off: { :on => [1,2,3,…], :off => [6,7,…] }

  • on : [ 1, 2, 3, … ]

  • off : [ 1, 2, 3, … ]

Parameters:

  • type (:ports, :on_off, :on, :off) (defaults to: :ports)

    Type of returned value



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/exsys/managed-usb.rb', line 131

def get(type = :ports)
    val = _get
    h   = PORTS.reduce({}) {|acc, obj|
         acc.merge(obj => (val & (1 << (obj-1))).positive?)
    }

    case type
    when :ports
        h
    when :on_off
        h.reduce({}) {|acc, (k,v)|
            acc.merge(v ? :on : :off => [ k ]) {|k,o,n| o + n  }
        }
    when :on
        h.select {|k,v| v }.keys
    when :off
        h.reject {|k,v| v }.keys
    else
        raise ArgumentError
    end
end

#off(*ports, commit: false) ⇒ Object

Turn off all or specified ports

Parameters:

  • commit (Boolean) (defaults to: false)

    Commit to flash memory



50
51
52
# File 'lib/exsys/managed-usb.rb', line 50

def off(*ports, commit: false)
    _set(_get & ~mask(ports, :all), commit: commit)
end

#on(*ports, commit: false) ⇒ Object

Turn on all or specified ports

Parameters:

  • commit (Boolean) (defaults to: false)

    Commit to flash memory



43
44
45
# File 'lib/exsys/managed-usb.rb', line 43

def on(*ports, commit: false)
    _set(_get | mask(ports, :all), commit: commit)
end

#password(new) ⇒ Object

Change the hub protection password

Raises:

  • (ArgumentError)


171
172
173
174
175
176
177
178
# File 'lib/exsys/managed-usb.rb', line 171

def password(new)
    new = PASSWORD                           if new.nil?
    raise ArgumentError, 'password too long' if new.size > 8
    new_password = new.ljust(8)
    action('CP', @password, new_password)
    @password = new_password
    self
end

#resetObject

Note:

power is not maintained accros a reset

Perform a hub reset action



166
167
168
# File 'lib/exsys/managed-usb.rb', line 166

def reset
    action('RH', @password, reply: false).then { self }
end

#restoreObject

Restore port states from the flash memory



154
155
156
# File 'lib/exsys/managed-usb.rb', line 154

def restore
    action('RD', @password).then { self }
end

#set(dataset, default = nil, commit: false) ⇒ Object

Set state for the specified ports

Port specification can have one of the folling format

  1. hash of port values: { 1 => :on, 2 => :off, …}

  2. hash of port states: { :on => [1, 3], :off => 4 }

In the case 1. the state values can be specified by

  • True: 1, :on, :ON, :true, :TRUE, true

  • False: 0, :off, :OFF, :false, :FALSE, false

The port states that are not specified will acquire the value specified by the default parameter (nil being the hub port current value)

Parameters:

  • dataset (Hash)

    Port state specification

  • default (Boolean, nil) (defaults to: nil)

    Default value to use if unspecified

  • commit (Boolean) (defaults to: false)

    Commit to flash memory



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/exsys/managed-usb.rb', line 73

def set(dataset, default = nil, commit: false)
    val = _get

    # Normalize
    keys = dataset.keys        
    if (keys - PORTS).empty?
        dataset = dataset.transform_values do |v|
            case v
            when * TRUE_LIST then true
            when *FALSE_LIST then false
            when nil
            else raise ArgumentError
            end
        end
    elsif (keys - [:on, :off]).empty?
        on  = Array(dataset[:on ])
        off = Array(dataset[:off])
        
        unless (on & off).empty?
            raise ArgumentError, "on/off overlap"
        end
        
        dataset = {}
        dataset.merge!(on .to_h {|k| [k, true  ] })
        dataset.merge!(off.to_h {|k| [k, false ] })
    else
        raise ArgumentError
    end

    # Fill unspecified
    unless default.nil?
        (PORTS - dataset.keys).each do |k|
            dataset.merge!(k => default)
        end
    end

    # Compute value
    dataset.compact.each do |k,v|
        flg = 1 << (k-1)
        if v
        then val |=  flg
        else val &= ~flg
        end
    end
    
    _set(val, commit: commit)
end

#toggle(*ports, commit: false) ⇒ Object

Toggle all or specified ports

Parameters:

  • commit (Boolean) (defaults to: false)

    Commit to flash memory



36
37
38
# File 'lib/exsys/managed-usb.rb', line 36

def toggle(*ports, commit: false)
    _set(_get ^ mask(ports, :all), commit: commit)
end