module StateMate::Adapters::PMSet

Constants

MODES

whitelist of modes we handle mapped to their `pmset` flag

there is also a UPS mode, but i don't know what it looks like

MODE_RE

regexp to pick the mode headers out of `pmset -g custom` output

SETTINGS

a whitelist of settings to parse, since the output of `pmset -g custom` can include lines like

Sleep On Power Button 1

which makes it hard to parse in general (spaces in key name and between key name and value).

from

SETTING_RE

regexp to pick the settings and values out of other lines of `pmset -g custom`

Public Class Methods

parse(input) click to toggle source

@api util pure

parse the output of `pmset -g custom`.

since keys can apparently have spaces in them (like “Sleep On Power Button”) and are seperated by spaces, it uses the {.SETTINGS} whitelist.

settings are saved at

/Library/Preferences/SystemConfiguration/com.apple.PowerManagement.plist

which might be a possible site for reading and writing, but seems safer to use `pmset`, and should satify needs for now.

@param input [String] output of `pmset -g custom`.

on my mbp it looks like

    Battery Power:
      lidwake              1
      autopoweroff         1
      autopoweroffdelay    14400
      standbydelay         10800
      standby              1
      ttyskeepawake        1
      hibernatemode        3
      darkwakes            0
      gpuswitch            2
      hibernatefile        /var/vm/sleepimage
      displaysleep         5
      sleep                5
      acwake               0
      halfdim              1
      lessbright           0
      disksleep            10
    AC Power:
      lidwake              1
      autopoweroff         0
      autopoweroffdelay    0
      standbydelay         0
      standby              0
      ttyskeepawake        1
      hibernatemode        3
      darkwakes            1
      gpuswitch            0
      hibernatefile        /var/vm/sleepimage
      womp                 0
      displaysleep         5
      networkoversleep     0
      sleep                10
      acwake               0
      halfdim              1
      disksleep            10

@return [Hash<String, Hash<String, String>>] hash of section titles

(like "Battery Power") to hashes of string keys to *sting* values
(does not turn numeric strings into integers).
# File lib/state_mate/adapters/pmset.rb, line 214
def self.parse input
  sections = {}
  section = {}
  
  input.lines.each do |line|
    if m = line.match(MODE_RE)
      section = {}
      sections[m[1]] = section
    else
      if m = line.match(SETTING_RE)
        section[m[1]] = m[2]
      end
    end
  end
  sections
end
read(key, options = {}) click to toggle source

@api adapter

Reads pm settings.

@param [Array<String>] key

Key path to read:

-   `[]` gets everything, returning a hash
    `{<mode> => {<setting> => <value>}}`.

    `PMSet.read []` looks something like:

        {"Battery Power"=>
          {"lidwake"=>"1",
           "autopoweroff"=>"1",
           ...},
         "AC Power"=>
          {"lidwake"=>"1",
           "autopoweroff"=>"1",
           ...}}

-   `[<mode>]` gets a hash of `{<setting> => <value>}` for that mode.

    `PMSet.read ["AC Power"]` looks something like:

        {"lidwake"=>"1",
         "autopoweroff"=>"1",
         ...}

-   `[<mode>, <setting>]` gets a string value.

    `PMSet.read ["AC Power", "lidwake"]` looks something like `"1"`

In addition:

-   `<mode>` must be in the keys of {.MODES}
-   `<setting>` must be in {.SETTINGS}

@param [Hash] options

Unused (part of adapter `.read` method signature).

@return [Hash<String, Hash<String, String>>]

Hash of everything when `key` is `[]`.

@return [Hash<String, String>]

Hash of values for mode when `key` is `[<mode>]`.

@return [String]

Value when `key` is `[<mode>, <setting>]`.

@raise [ArgumentError]

If the key is not found.
# File lib/state_mate/adapters/pmset.rb, line 286
  def self.read key, options = {}
    # read all the settings.
    settings = parse Cmds.out!('pmset -g custom')
    
    value = settings
    key.each do |seg|
      unless value.key? seg
        raise ArgumentError.new binding.erb <<-END
          bad segment #{ seg.inspect } in key #{ key }.
          
          pm settings:
          
          <%= settings.pretty_inspect %>
        END
      end
      value = value[seg]
    end
    
    value
  end
write(key, value, options = {}) click to toggle source

@api adapter

writes pm settings.

@param key [Array<String>] must be a two-element array of strings where

the first element is a key of {.MODES} and the second is in {.SETTINGS}.

@param value [String] value to write.

@return nil

@raise [ArgumentError] if `key` is bad.

# File lib/state_mate/adapters/pmset.rb, line 320
  def self.write key, value, options = {}
    unless key.is_a?(Array) && key.length == 2
      raise ArgumentError.new binding.erb <<-END
        key must be a pair [mode, setting], not <%= key.inspect %>.
      END
    end
    
    mode, setting = key
    
    if MODES[mode].nil?
      raise ArgumentError.new binding.erb <<-END
        first key element must be one of
        
        <%= MODES.keys.pretty_inspect %>
        
        found <%= mode.inspect %>
      END
    end
    
    unless SETTINGS.include? setting
      raise ArgumentError.new binding.erb <<-END
        second key element must be one of
        
        <%= SETTINGS.pretty_inspect %>
        
        found <%= setting.inspect %>
      END
    end
    
    Cmds! "sudo pmset -#{ MODES[mode] } %{setting} %{value}",
      setting: setting,
      value: value
    
    nil
  end