lib/senec/local/request.rb
require_relative 'value'
require_relative 'constants'
module Senec
module Local
class Request
def initialize(connection:, body: BASIC_REQUEST, state_names: nil)
@connection = connection
@body = body
@state_names = state_names
end
attr_reader :connection, :body, :state_names
def perform!
parsed_response
true
end
def house_power
get('ENERGY', 'GUI_HOUSE_POW')
end
def inverter_power
get('ENERGY', 'GUI_INVERTER_POWER')
end
def mpp_power
get('PV1', 'MPP_POWER')
end
def power_ratio
get('PV1', 'POWER_RATIO')
end
def bat_power
get('ENERGY', 'GUI_BAT_DATA_POWER')
end
def bat_fuel_charge
get('ENERGY', 'GUI_BAT_DATA_FUEL_CHARGE')
end
def bat_charge_current
get('ENERGY', 'GUI_BAT_DATA_CURRENT')
end
def bat_voltage
get('ENERGY', 'GUI_BAT_DATA_VOLTAGE')
end
def grid_power
get('ENERGY', 'GUI_GRID_POW')
end
def wallbox_charge_power
get('WALLBOX', 'APPARENT_CHARGING_POWER')
end
def case_temp
get('TEMPMEASURE', 'CASE_TEMP')
end
def application_version
get('WIZARD', 'APPLICATION_VERSION')
end
def current_state_code
get('ENERGY', 'STAT_STATE')
end
def current_state_name
throw RuntimeError, 'No state names provided!' unless state_names
state_names[current_state_code]
end
def measure_time
web_time = get('RTC', 'WEB_TIME')
utc_offset = get('RTC', 'UTC_OFFSET')
web_time - (utc_offset * 60)
end
def response_duration
raw_response.env[:duration]
end
def get(*keys)
return unless parsed_response
value = parsed_response.dig(*keys)
if value.is_a?(Array)
value.map do |v|
Value.new(v).decoded
end
elsif value
Value.new(value).decoded
else
raise Error, "Value missing for #{keys.join('.')}"
end
rescue Senec::Local::DecodingError => e
raise Error, "Decoding failed for #{keys.join('.')}: #{e.message}"
end
def path
'/lala.cgi'
end
private
def parsed_response
@parsed_response ||= JSON.parse(raw_response.body)
end
def raw_response
@raw_response ||= begin
response = connection.post(path, request_body, request_header)
raise Error, response.status unless response.success?
response
end
end
def request_body
JSON.generate(body)
end
def request_header
{
'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8',
'Accept' => 'application/json, text/javascript, */*; q=0.01'
}
end
end
end
end