Class: Growatt::Client

Inherits:
API
  • Object
show all
Defined in:
lib/growatt/client.rb

Overview

Note:

No official API documentation is available; this was reverse-engineered.

Wrapper for the Growatt REST API

This class provides methods to interact with the Growatt API, including:

  • Retrieving plant and inverter data

  • Managing inverters (turning them on/off, updating settings)

  • Handling authentication and session data

Instance Method Summary collapse

Methods inherited from API

#config

Methods included from Authentication

#login

Methods included from Connection

#connection

Constructor Details

#initialize(options = {}) ⇒ Client

Initializes the Growatt API client.

Parameters:

  • options (Hash) (defaults to: {})

    Additional options for the API client.



22
23
24
# File 'lib/growatt/client.rb', line 22

def initialize(options = {})
  super(options)
end

Instance Method Details

#device_list(plant_id) ⇒ Array

Retrieves a list of devices in a plant.

Parameters:

  • plant_id (String)

    The plant ID.

Returns:

  • (Array)

    A list of devices.



73
74
75
# File 'lib/growatt/client.rb', line 73

def device_list(plant_id)
  plant_info(plant_id).deviceList
end

#export_limit(serial_number, enable, value = nil) ⇒ Boolean

Sets export limit for an inverter.

Parameters:

  • serial_number (String)

    The inverter’s serial number.

  • enable (String)

    ‘ExportLimit::DISABLE`, `ExportLimit::WATT`, or `ExportLimit::PERCENTAGE`.

  • value (Numeric, nil) (defaults to: nil)

    The export limit value (required unless disabled).

Returns:

  • (Boolean)

    ‘true` if the setting update was successful.



143
144
145
146
147
148
149
150
151
# File 'lib/growatt/client.rb', line 143

def export_limit(serial_number, enable, value = nil)
  if ExportLimit::DISABLE.eql? enable
    params = [0]
  else
    validate_export_parameters(enable, value)
    params = [1, value, enable]
  end
  update_inverter_setting(serial_number, 'maxSetApi', 'backflow_setting', params)
end

#inverter_control_data(inverter_id) ⇒ Hash

Retrieves data for inverter control.

Parameters:

  • inverter_id (String)

    The inverter’s serial number.

Returns:

  • (Hash)

    The inverter’s control data.



90
91
92
93
94
95
# File 'lib/growatt/client.rb', line 90

def inverter_control_data(inverter_id)
  _inverter_api({
    'op': 'getMaxSetData',
    'serialNum': inverter_id
  }).obj.maxSetBean
end

#inverter_data(inverter_id, type = Timespan::DAY, date = Time.now) ⇒ Hash

Retrieves inverter data based on timespan.

Parameters:

  • inverter_id (String)

    The inverter’s ID.

  • type (String) (defaults to: Timespan::DAY)

    The timespan type.

  • date (Time) (defaults to: Time.now)

    The date (default: ‘Time.now`).

Returns:

  • (Hash)

    The inverter data.



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/growatt/client.rb', line 175

def inverter_data(inverter_id, type = Timespan::DAY, date = Time.now)
  operator =
    case type
    when Timespan::DAY then 'getInverterData_max'
    when Timespan::MONTH then 'getMaxMonthPac'
    when Timespan::YEAR then 'getMaxYearPac'
    end

  _inverter_api({
    'op': operator,
    'id': inverter_id,
    'type': 1,
    'date': timespan_date(type, date)
  })
end

#inverter_list(plant_id) ⇒ Array

Retrieves a list of inverters in a plant.

Parameters:

  • plant_id (String)

    The plant ID.

Returns:

  • (Array)

    A list of inverters.



81
82
83
84
# File 'lib/growatt/client.rb', line 81

def inverter_list(plant_id)
  devices = device_list(plant_id)
  devices.select { |device| 'inverter'.eql? device.deviceType }
end

#inverter_on?(serial_number) ⇒ Boolean

Checks if an inverter is turned on.

Parameters:

  • serial_number (String)

    The inverter’s serial number.

Returns:

  • (Boolean)

    ‘true` if the inverter is on, `false` otherwise.



132
133
134
135
# File 'lib/growatt/client.rb', line 132

def inverter_on?(serial_number)
  status = inverter_control_data(serial_number)
  Inverter::ON.eql? status.max_cmd_on_off
end

#login_infoHash?

Retrieves login session data.

Returns:

  • (Hash, nil)

    The login data stored in @login_data.



29
30
31
# File 'lib/growatt/client.rb', line 29

def 
  @login_data
end

#plant_detail(plant_id, type = Timespan::DAY, date = Time.now) ⇒ Hash

Retrieves detailed information about a plant.

Parameters:

  • plant_id (String)

    The plant ID.

  • type (String) (defaults to: Timespan::DAY)

    The timespan type (default: ‘Timespan::DAY`).

  • date (Time) (defaults to: Time.now)

    The date for the requested timespan (default: ‘Time.now`).

Returns:

  • (Hash)

    The plant details.



48
49
50
51
52
53
54
# File 'lib/growatt/client.rb', line 48

def plant_detail(plant_id, type = Timespan::DAY, date = Time.now)
  _plant_detail({
    'plantId': plant_id,
    'type': type,
    'date': timespan_date(type, date)
  })
end

#plant_info(plant_id) ⇒ Hash

Retrieves plant information.

Parameters:

  • plant_id (String)

    The plant ID.

Returns:

  • (Hash)

    Plant information, including available devices.



60
61
62
63
64
65
66
67
# File 'lib/growatt/client.rb', line 60

def plant_info(plant_id)
  _plant_info({
    'op': 'getAllDeviceList',
    'plantId': plant_id,
    'pageNum': 1,
    'pageSize': 1
  })
end

#plant_list(user_id = nil) ⇒ Hash

Retrieves a list of plants associated with a user.

Parameters:

  • user_id (String, nil) (defaults to: nil)

    The user ID; if nil, it defaults to the logged-in user’s ID.

Returns:

  • (Hash)

    The list of plants.



37
38
39
40
# File 'lib/growatt/client.rb', line 37

def plant_list(user_id = nil)
  user_id ||= ['user']['id']
  _plant_list({ 'userId': user_id })
end

#timespan_date(timespan = Timespan::DAY, date = Time.now) ⇒ String

Utility function to get a formatted date based on timespan.

Parameters:

  • timespan (String) (defaults to: Timespan::DAY)

    The timespan type (‘Timespan::DAY`, `Timespan::MONTH`, `Timespan::YEAR`).

  • date (Time) (defaults to: Time.now)

    The date (default: ‘Time.now`).

Returns:

  • (String)

    The formatted date.



158
159
160
161
162
163
164
165
166
167
# File 'lib/growatt/client.rb', line 158

def timespan_date(timespan = Timespan::DAY, date = Time.now)
  case timespan
  when Timespan::YEAR
    date.strftime("%Y")
  when Timespan::MONTH
    date.strftime("%Y-%m")
  when Timespan::DAY
    date.strftime("%Y-%m-%d")
  end
end

#turn_inverter(serial_number, on = true) ⇒ Boolean

Turns an inverter on or off.

Parameters:

  • serial_number (String)

    The inverter’s serial number.

  • on (Boolean) (defaults to: true)

    ‘true` to turn on, `false` to turn off.

Returns:

  • (Boolean)

    ‘true` if the operation was successful.



123
124
125
126
# File 'lib/growatt/client.rb', line 123

def turn_inverter(serial_number, on = true)
  onoff = (on ? Inverter::ON : Inverter::OFF)
  update_inverter_setting(serial_number, 'maxSetApi', 'max_cmd_on_off', [onoff])
end

#update_inverter_setting(serial_number, command, param_id, parameters) ⇒ Boolean

Updates an inverter’s setting.

Parameters:

  • serial_number (String)

    The inverter’s serial number.

  • command (String)

    The command to execute.

  • param_id (String)

    The parameter ID.

  • parameters (Array, Hash)

    The parameters to send.

Returns:

  • (Boolean)

    ‘true` if the update was successful, `false` otherwise.



104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/growatt/client.rb', line 104

def update_inverter_setting(serial_number, command, param_id, parameters)
  command_parameters = {
    'op': command,
    'serialNum': serial_number,
    'paramId': param_id
  }

  parameters = parameters.map.with_index { |value, index| ["param#{index + 1}", value] }.to_h if parameters.is_a? Array
  self.format = 'x-www-form-urlencoded'
  data = JSON.parse(post('newTcpsetAPI.do', command_parameters.merge(parameters)).body)
  self.format = :json
  data['success']
end