class SmaApi::Http

Net::HTTP wrapper for the SMA Inverter web interface

Public Class Methods

new(host:, password:, sid: nil) click to toggle source
# File lib/sma_api/http.rb, line 9
def initialize(host:, password:, sid: nil)
  @host = host
  @password = password
  @sid = sid || ''
end

Public Instance Methods

create_session() click to toggle source

Creates a session using the supplied password

@raise [SmaApi::Error] Creating session failed, for example if the password is wrong @return [String] the session id that will be used in subsequent requests.

# File lib/sma_api/http.rb, line 55
def create_session
  payload = {
    right: 'usr', pass: @password
  }
  result = JSON.parse(http.post('/dyn/login.json', payload.to_json).body).fetch('result', {})

  raise SmaApi::Error, 'Creating session failed' unless result['sid']

  @sid = result['sid']
end
destroy_session() click to toggle source

Logout and clear the session. This is the same as using Logout from the web interface

@return [String] An empty session id

# File lib/sma_api/http.rb, line 78
def destroy_session
  post('/dyn/logout.json', {})

  @sid = ''
end
download(url, path) click to toggle source

Download the file specified by url and store it in a file on the local file system.

@param url [String] URL without /fs prefix. It should start with a '/' @param path [String] Path of the local file

# File lib/sma_api/http.rb, line 37
def download(url, path)
  create_session if @sid.empty?

  file = File.open(path, 'wb')

  begin
    res = retrieve_file(url)

    file.write(res.body)
  ensure
    file.close
  end
end
post(url, payload = {}) click to toggle source

Perform a HTTP POST.

@param url [String] URL. It should start with a '/' @param payload [Hash] The payload that will be used in the post @return [Hash] The response

# File lib/sma_api/http.rb, line 20
def post(url, payload = {})
  create_session if @sid.empty?

  response = JSON.parse(http.post(url_with_sid(url), payload.to_json).body)

  return response unless response.key? 'err'

  raise SmaApi::Error, "Error #{response['err']} during request" unless response['err'] == 401

  create_session
  post(url, payload)
end
sid() click to toggle source

The current session id. If empty, it will create a new session

@return [String] the session id that will be used in subsequent requests.

# File lib/sma_api/http.rb, line 69
def sid
  create_session if @sid.empty?

  @sid
end

Private Instance Methods

configure_http_client() click to toggle source
# File lib/sma_api/http.rb, line 108
def configure_http_client
  client =  Net::HTTP.new(@host, 443)
  client.use_ssl = true
  client.verify_mode = OpenSSL::SSL::VERIFY_NONE

  client
end
http() click to toggle source
# File lib/sma_api/http.rb, line 104
def http
  @http ||= configure_http_client
end
retrieve_file(url) click to toggle source
# File lib/sma_api/http.rb, line 90
def retrieve_file(url)
  res = http.get('/fs' + url_with_sid(url))

  unless res.code == '200'
    # Try again because invalid sid does not result in a 401
    create_session
    res = http.get('/fs' + url_with_sid(url))

    raise "Error retrieving file (#{res.code} #{res.message})" unless res.code == '200'
  end

  res
end
url_with_sid(url) click to toggle source
# File lib/sma_api/http.rb, line 86
def url_with_sid(url)
  url + "?sid=#{@sid}"
end