Class: SouthAfricanAirQualityIndex::Client

Inherits:
Object
  • Object
show all
Includes:
Constants
Defined in:
lib/south_african_air_quality_index/client.rb

Constant Summary

Constants included from Constants

SouthAfricanAirQualityIndex::Constants::AQI_INDEX, SouthAfricanAirQualityIndex::Constants::BASE_PATH, SouthAfricanAirQualityIndex::Constants::BASE_PORT, SouthAfricanAirQualityIndex::Constants::BASE_URI, SouthAfricanAirQualityIndex::Constants::DATA_SOURCE_PORT, SouthAfricanAirQualityIndex::Constants::DEFAULT_INTERVAL, SouthAfricanAirQualityIndex::Constants::DEFAULT_PERCENT_VALID, SouthAfricanAirQualityIndex::Constants::HOURLY_REPORT, SouthAfricanAirQualityIndex::Constants::REPORT_TYPE, SouthAfricanAirQualityIndex::Constants::STATION_REPORT

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Constants

#calculate_aqi_range

Constructor Details

#initialize(base_path: BASE_PATH, port: BASE_PORT, verify_ssl: true) ⇒ Client

Returns a new instance of Client.



7
8
9
10
11
12
# File 'lib/south_african_air_quality_index/client.rb', line 7

def initialize(base_path: BASE_PATH, port: BASE_PORT, verify_ssl: true)
  @base_path = base_path
  @port = port
  @verify_ssl = verify_ssl
  @cookie = authorise
end

Instance Attribute Details

#base_pathObject (readonly)

Returns the value of attribute base_path.



5
6
7
# File 'lib/south_african_air_quality_index/client.rb', line 5

def base_path
  @base_path
end

#portObject (readonly)

Returns the value of attribute port.



5
6
7
# File 'lib/south_african_air_quality_index/client.rb', line 5

def port
  @port
end

#stationsObject (readonly)

Memoize stations as they are unlikely to change often



48
49
50
# File 'lib/south_african_air_quality_index/client.rb', line 48

def stations
  @stations
end

#verify_sslObject (readonly)

Returns the value of attribute verify_ssl.



5
6
7
# File 'lib/south_african_air_quality_index/client.rb', line 5

def verify_ssl
  @verify_ssl
end

Class Method Details

.api_versionObject

This is the version of the API docs this client was built off-of



19
20
21
# File 'lib/south_african_air_quality_index/client.rb', line 19

def self.api_version
  'v1 2024-03-18'
end

.compatible_api_versionObject



14
15
16
# File 'lib/south_african_air_quality_index/client.rb', line 14

def self.compatible_api_version
  'v1'
end

Instance Method Details

#fetch_regions_from_htmlObject



37
38
39
40
41
42
43
44
45
# File 'lib/south_african_air_quality_index/client.rb', line 37

def fetch_regions_from_html
  # https://saaqis.environment.gov.za/Report/HourlyReports
  response = send_request(http_method: :get, path: 'Report/HourlyReports')
  doc = Nokogiri::HTML(response["body"])

  # JSON.parse(content).map { |j| j.dig("stations")}.flatten
  # alex = JSON.parse(content).map { |j| j.dig("stations")}.flatten.select { |st| st["name"] == "Alexandra-NAQI" }.first
  find_and_parse_m_regions(doc)
end

#multi_station_report(station_names, start_date, end_date, interval: DEFAULT_INTERVAL, report_type: REPORT_TYPE) ⇒ Object

This now will only return HTML TODO: Parse the HTML May not work:



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/south_african_air_quality_index/client.rb', line 100

def multi_station_report(station_names, start_date, end_date, interval: DEFAULT_INTERVAL, report_type: REPORT_TYPE)
  extracted_stations = selected_stations(station_names)

  monitor_channels_by_station_id = extracted_stations.map { |station|
    [station['stationId'].to_s, fetch_monitor_ids(station)]
  }.to_h

  body = {
    "monitorChannelsByStationId": monitor_channels_by_station_id,
    "reportName": HOURLY_REPORT,
    "startDateAbsolute": start_date.to_s,
    "endDateAbsolute": end_date.to_s,
    "startDate": "/Date(#{Time.parse(start_date.to_s).to_i})/",
    "endDate": "/Date(#{Time.parse(end_date.to_s).to_i})/",
    "reportType": REPORT_TYPE,
    "fromTb": DEFAULT_INTERVAL,
    "toTb": DEFAULT_INTERVAL
  }

  monitor_channels_by_station_id.each.with_index do |pair, index|
    hsh = {
      "monitorChannelsByStationId[#{index}].Key": pair[0],
      "monitorChannelsByStationId[#{index}].Value": pair[1]
    }

    body = body.merge(hsh)
  end

  send_request(http_method: :get, path: 'report/MultiStationTable', body: body.to_json)
end

#regionsObject

Endpoints



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/south_african_air_quality_index/client.rb', line 24

def regions
  return @regions if @regions

  response = send_request(http_method: :get, path: '/v1/envista/regions', port: DATA_SOURCE_PORT, port_in_path: true)

  if response["code"] != 200
    puts "Fallback SAAQIS region fetch!"
    @regions ||= fetch_regions_from_html
  else
    @regions ||= response["body"]
  end
end

#selected_stations(station_names) ⇒ Object



65
66
67
68
69
70
71
72
73
# File 'lib/south_african_air_quality_index/client.rb', line 65

def selected_stations(station_names)
  unless station_names.is_a?(Array)
    station_names = [station_names]
  end

  stations.select do |station|
    station_matches?(station_names, station)
  end
end

#station_report(station_name, start_date, end_date, interval: DEFAULT_INTERVAL, report_type: REPORT_TYPE, precent_valid: DEFAULT_PERCENT_VALID) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/south_african_air_quality_index/client.rb', line 75

def station_report(station_name, start_date, end_date, interval: DEFAULT_INTERVAL, report_type: REPORT_TYPE, precent_valid: DEFAULT_PERCENT_VALID)
  station = selected_stations([station_name]).first
  return if station.empty?

  params = {
    filterChannels: fetch_monitor_ids(station),
    from: parse_time(start_date.to_s),
    to: parse_time(end_date.to_s),
    fromTimebase: interval,
    toTimebase: interval,
    precentValid: precent_valid,
    timeBeginning: false,
    useBackWard: true,
    unitConversion: false,
    includeSummary: true,
    onlySummary: false, # TODO: Parameter?
  }

  path = "v1/envista/stations/#{station['stationId']}/#{report_type}"
  send_request(http_method: :get, path: path, params: params, port: DATA_SOURCE_PORT, port_in_path: true)
end

#stations_from_code(codes, build_for_response: false) ⇒ Object



55
56
57
58
59
60
61
62
63
# File 'lib/south_african_air_quality_index/client.rb', line 55

def stations_from_code(codes, build_for_response: false)
  unless codes.is_a?(Array)
    codes = [codes]
  end

  stations.select do |station|
    codes.map(&:to_s).include?(station["stationId"].to_s)
  end
end