defmodule GeoTherminator.PumpAPI.Device.API do alias GeoTherminator.PumpAPI.HTTP alias GeoTherminator.PumpAPI.Device alias GeoTherminator.PumpAPI.Auth @spec device_info(Auth.User.t(), Device.InstallationInfo.t()) :: Device.t() def device_info(user, installation) do url = Application.get_env(:geo_therminator, :api_device_url) |> String.replace("{id}", to_string(installation.id)) req = HTTP.authed_req(user, :get, url) {:ok, response} = Finch.request(req, HTTP) json = Jason.decode!(response.body) last_online = NaiveDateTime.from_iso8601!(json["lastOnline"]) created_when = NaiveDateTime.from_iso8601!(json["createdWhen"]) %Device{ id: json["id"], device_id: json["deviceId"], is_online: json["isOnline"], last_online: last_online, created_when: created_when, mac_address: json["macAddress"], name: json["name"], model: json["model"], retailer_access: json["retailerAccess"] } end @spec status(Auth.User.t(), Device.t()) :: Device.Status.t() def status(user, device) do url = Application.get_env(:geo_therminator, :api_device_status_url) |> String.replace("{id}", to_string(device.id)) req = HTTP.authed_req(user, :get, url) {:ok, response} = Finch.request(req, HTTP) json = Jason.decode!(response.body) %Device.Status{ heating_effect: json["heatingEffect"], is_heating_effect_set_by_user: json["isHeatingEffectSetByUser"] } end @spec register_info(Auth.User.t(), Device.t()) :: Device.RegisterCollection.t() def register_info(user, device) do url = Application.get_env(:geo_therminator, :api_device_register_url) |> String.replace("{id}", to_string(device.id)) req = HTTP.authed_req(user, :get, url) {:ok, response} = Finch.request(req, HTTP) json = Jason.decode!(response.body) registers = Enum.map(json, fn item -> {:ok, timestamp, _} = DateTime.from_iso8601(item["timeStamp"]) %Device.Register{ register_name: item["registerName"], register_value: item["registerValue"], timestamp: timestamp } end) %Device.RegisterCollection{ outdoor_temp: find_register(registers, "REG_OUTDOOR_TEMPERATURE"), supply_out: find_register(registers, "REG_SUPPLY_LINE"), supply_in: find_register(registers, "REG_OPER_DATA_RETURN"), desired_supply: find_register(registers, "REG_DESIRED_SYS_SUPPLY_LINE_TEMP"), brine_out: find_register(registers, "REG_BRINE_OUT"), brine_in: find_register(registers, "REG_BRINE_IN"), hot_water_temp: find_register(registers, "REG_HOT_WATER_TEMPERATURE") } end @spec opstat(Auth.User.t(), Device.t()) :: Device.OpStat.t() def opstat(user, device) do url = Application.get_env(:geo_therminator, :api_device_opstat_url) |> String.replace("{id}", to_string(device.id)) req = HTTP.authed_req(user, :get, url) {:ok, response} = Finch.request(req, HTTP) json = Jason.decode!(response.body) registers = Enum.map(json, fn item -> {:ok, timestamp, _} = DateTime.from_iso8601(item["timeStamp"]) %Device.Register{ register_name: item["registerName"], register_value: item["registerValue"], timestamp: timestamp } end) priority_register = find_register(registers, "REG_OPERATIONAL_STATUS_PRIO1") priority_register_fallback = find_register(registers, "REG_OPERATIONAL_STATUS_PRIORITY_BITMASK") {mapping, register} = if not is_nil(priority_register) do {Application.get_env(:geo_therminator, :api_opstat_mapping), priority_register} else {Application.get_env(:geo_therminator, :api_opstat_bitmask_mapping), priority_register_fallback} end %Device.OpStat{ priority: Map.get(mapping, register.register_value, :unknown) } end @spec set_temp(Auth.User.t(), Device.t(), integer()) :: :ok | {:error, String.t()} def set_temp(user, device, temp) do url = Application.get_env(:geo_therminator, :api_device_reg_set_url) |> String.replace("{id}", to_string(device.id)) register_index = Application.get_env(:geo_therminator, :api_device_temp_set_reg_index) client_id = Application.get_env(:geo_therminator, :api_device_reg_set_client_id) req = HTTP.authed_req(user, :post, url, [], %{ registerIndex: register_index, registerValue: temp, clientUuid: client_id }) IO.inspect(req) {:ok, response} = Finch.request(req, HTTP) if response.status == 200 do :ok else {:error, "Error #{response.status}: " <> response.body} end end defp find_register(registers, name) do Enum.find(registers, &(&1.register_name == name)) end end