diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 66a2c14c7..2d2b5f577 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ env: # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) BUILD_TYPE: Release DEFAULT_BRANCH: develop - WX_VERSION: '3.2.4' + WX_VERSION: '3.2.6' jobs: build-ubuntu: diff --git a/deploy/runtime/defaults/Geothermal Power_All Equity Partnership Flip.json b/deploy/runtime/defaults/Geothermal Power_All Equity Partnership Flip.json index 387b17ff1..038da2e7d 100644 --- a/deploy/runtime/defaults/Geothermal Power_All Equity Partnership Flip.json +++ b/deploy/runtime/defaults/Geothermal Power_All Equity Partnership Flip.json @@ -29,6 +29,7 @@ 0.0, 0.0 ], + "allow_reservoir_replacements": 0.0, "ambient_pressure": 14.7, "analysis_period": 25.0, "analysis_period_warning": "No messages.", diff --git a/deploy/runtime/defaults/Geothermal Power_LCOE Calculator.json b/deploy/runtime/defaults/Geothermal Power_LCOE Calculator.json index eb2a563eb..2070a7410 100644 --- a/deploy/runtime/defaults/Geothermal Power_LCOE Calculator.json +++ b/deploy/runtime/defaults/Geothermal Power_LCOE Calculator.json @@ -29,6 +29,7 @@ 0.0, 0.0 ], + "allow_reservoir_replacements": 0.0, "ambient_pressure": 14.7, "analysis_type": 0.0, "annual_albedo": "nan", diff --git a/deploy/runtime/defaults/Geothermal Power_Leveraged Partnership Flip.json b/deploy/runtime/defaults/Geothermal Power_Leveraged Partnership Flip.json index fe7c0d098..9a07cfdce 100644 --- a/deploy/runtime/defaults/Geothermal Power_Leveraged Partnership Flip.json +++ b/deploy/runtime/defaults/Geothermal Power_Leveraged Partnership Flip.json @@ -29,6 +29,7 @@ 0.0, 0.0 ], + "allow_reservoir_replacements": 0.0, "ambient_pressure": 14.7, "analysis_period": 25.0, "analysis_period_warning": "No messages.", diff --git a/deploy/runtime/defaults/Geothermal Power_Merchant Plant.json b/deploy/runtime/defaults/Geothermal Power_Merchant Plant.json index c4f3b3ae4..b86272fc8 100644 --- a/deploy/runtime/defaults/Geothermal Power_Merchant Plant.json +++ b/deploy/runtime/defaults/Geothermal Power_Merchant Plant.json @@ -29,6 +29,7 @@ 0.0, 0.0 ], + "allow_reservoir_replacements": 0.0, "ambient_pressure": 14.7, "analysis_period": 25.0, "analysis_period_warning": "No messages.", diff --git a/deploy/runtime/defaults/Geothermal Power_None.json b/deploy/runtime/defaults/Geothermal Power_None.json index 887d309cb..e6af395a7 100644 --- a/deploy/runtime/defaults/Geothermal Power_None.json +++ b/deploy/runtime/defaults/Geothermal Power_None.json @@ -29,6 +29,7 @@ 0.0, 0.0 ], + "allow_reservoir_replacements": 0.0, "ambient_pressure": 14.7, "analysis_type": 0.0, "annual_albedo": "nan", diff --git a/deploy/runtime/defaults/Geothermal Power_Sale Leaseback.json b/deploy/runtime/defaults/Geothermal Power_Sale Leaseback.json index c39aec6e7..7b97f76bc 100644 --- a/deploy/runtime/defaults/Geothermal Power_Sale Leaseback.json +++ b/deploy/runtime/defaults/Geothermal Power_Sale Leaseback.json @@ -29,6 +29,7 @@ 0.0, 0.0 ], + "allow_reservoir_replacements": 0.0, "ambient_pressure": 14.7, "analysis_period": 25.0, "analysis_period_warning": "No messages.", diff --git a/deploy/runtime/defaults/Geothermal Power_Single Owner.json b/deploy/runtime/defaults/Geothermal Power_Single Owner.json index c06546e04..098c1c0e2 100644 --- a/deploy/runtime/defaults/Geothermal Power_Single Owner.json +++ b/deploy/runtime/defaults/Geothermal Power_Single Owner.json @@ -29,6 +29,7 @@ 0.0, 0.0 ], + "allow_reservoir_replacements": 0.0, "ambient_pressure": 14.7, "analysis_period": 25.0, "analysis_period_warning": "No messages.", diff --git a/deploy/runtime/ui/Geothermal Costs.json b/deploy/runtime/ui/Geothermal Costs.json index d6786e379..794fc41b1 100644 --- a/deploy/runtime/ui/Geothermal Costs.json +++ b/deploy/runtime/ui/Geothermal Costs.json @@ -12904,7 +12904,8 @@ "\t\tssc_var( geothermal, 'design_temp', ${design_temp} );", "\t\tssc_var( geothermal, 'specify_pump_work', ${specify_pump_work} ); // INTEGER", "\t\tssc_var( geothermal, 'specified_pump_work_amount', ${specified_pump_work_amount} );", - "", + "\t\t\r", + "\t\tssc_var( geothermal, 'allow_reservoir_replacements', ${allow_reservoir_replacements});", "\t\t// detailed geothermal inputs", "\t\tssc_var( geothermal, 'rock_thermal_conductivity', ${rock_thermal_conductivity} );", "\t\tssc_var( geothermal, 'rock_specific_heat', ${rock_specific_heat} );", diff --git a/deploy/runtime/ui/Geothermal OM Costs.json b/deploy/runtime/ui/Geothermal OM Costs.json index b7948c7bf..7993b776d 100644 --- a/deploy/runtime/ui/Geothermal OM Costs.json +++ b/deploy/runtime/ui/Geothermal OM Costs.json @@ -1,7 +1,7 @@ { "Name": "Geothermal OM Costs", - "Width": 778.0, - "Height": 209.0, + "Width": 551.0, + "Height": 206.0, "FormObjects": { "Button": { "Visible": 1.0, @@ -12,11 +12,11 @@ }, "X": { "Type": 3.0, - "Integer": 111.0 + "Integer": 24.0 }, "Y": { "Type": 3.0, - "Integer": 78.0 + "Integer": 57.0 }, "Width": { "Type": 3.0, @@ -61,7 +61,7 @@ }, "Height": { "Type": 3.0, - "Integer": 180.0 + "Integer": 108.0 }, "Tool Tip": { "Type": 5.0, @@ -110,7 +110,8 @@ "\t}\r", "\tssc_var( geothermal, 'resource_depth', ${resource_depth} );\r", "\tssc_var( geothermal, 'dt_prod_well', ${dt_prod_well} );\t\r", - "\tssc_var( geothermal, 'prod_well_choice', ${prod_well_choice} );\t\t\t\t\t\t\t\t\t\t\t\t\r", + "\tssc_var( geothermal, 'prod_well_choice', ${prod_well_choice} );\t\r", + "\tssc_var( geothermal, 'allow_reservoir_replacements', ${allow_reservoir_replacements});\t\t\t\t\t\t\t\t\t\t\t\r", "\t// Other inputs\t\t\t\t\t\t\t \r", "\tssc_var( geothermal, 'geothermal_analysis_period', ${geothermal_analysis_period} ); // INTEGER\r", "\tssc_var( geothermal, 'model_choice', ${model_choice} ); // INTEGER\r", diff --git a/deploy/runtime/ui/Geothermal Plant and Equipment.json b/deploy/runtime/ui/Geothermal Plant and Equipment.json index 6fb88feec..521c28963 100644 --- a/deploy/runtime/ui/Geothermal Plant and Equipment.json +++ b/deploy/runtime/ui/Geothermal Plant and Equipment.json @@ -476,6 +476,47 @@ } } }, + "CheckBox": { + "Visible": 1.0, + "ObjectProperties": { + "Name": { + "Type": 5.0, + "String": "allow_reservoir_replacements" + }, + "X": { + "Type": 3.0, + "Integer": 42.0 + }, + "Y": { + "Type": 3.0, + "Integer": 483.0 + }, + "Width": { + "Type": 3.0, + "Integer": 249.0 + }, + "Height": { + "Type": 3.0, + "Integer": 24.0 + }, + "Tool Tip": { + "Type": 5.0, + "String": "" + }, + "Caption": { + "Type": 5.0, + "String": "Allow reservoir replacements" + }, + "State": { + "Type": 2.0, + "Boolean": 1.0 + }, + "TabOrder": { + "Type": 3.0, + "Integer": -1.0 + } + } + }, "Numeric": { "Visible": 1.0, "ObjectProperties": { @@ -1552,7 +1593,7 @@ }, "Y": { "Type": 3.0, - "Integer": 483.0 + "Integer": 513.0 }, "Width": { "Type": 3.0, @@ -2967,7 +3008,7 @@ }, "Y": { "Type": 3.0, - "Integer": 483.0 + "Integer": 513.0 }, "Width": { "Type": 3.0, @@ -3496,6 +3537,19 @@ "sscVariableName": "", "sscVariableValue": "" }, + "allow_reservoir_replacements": { + "Version": 4.0, + "Type": 1.0, + "Label": "Allow reservoir replacements", + "Units": "0/1", + "Group": "Geothermal Plant and Equipment", + "IndexLabels": "", + "Flags": 3.0, + "DefaultValue": 0.0, + "UIObject": "CheckBox", + "sscVariableName": "", + "sscVariableValue": "" + }, "ambient_pressure": { "Version": 4.0, "Type": 1.0, @@ -4100,7 +4154,7 @@ "//\tssc_var( obj, 'adjust:constant', 0.0 );", "//\tssc_var( obj, 'adjust', {\"constant\" = 0.0} );", "\tssc_var( obj, 'adjust_constant', 0.0 );\r", - "", + "\tssc_var( obj, 'allow_reservoir_replacements', ${allow_reservoir_replacements});", "\tssc_var( obj, 'resource_type', ${resource_type} ); // INTEGER", "\tssc_var( obj, 'resource_temp', ${resource_temp} );", "\tssc_var( obj, 'resource_depth', ${resource_depth} );", @@ -4309,6 +4363,7 @@ "\ton_change{'prod_well_choice'}();\r", "\tloss_adjustment_set();\r", "\ton_change{'use_weather_file_conditions'}();\r", + "\ton_change{'allow_reservoir_replacements'}();\r", "\trefresh();\r", "};\t\r", "\r", @@ -4364,6 +4419,11 @@ "\tenable('wet_bulb_temp_input', check == 0);\r", "\tenable('wet_bulb_temp_wf', check == 1);\r", "\trefresh();\r", + "};\r", + "\r", + "on_change{'allow_reservoir_replacements'} = define() {\r", + "\tcheck = value('allow_reservoir_replacements');\r", + "\tenable('temp_decline_max', check);\r", "};" ] } \ No newline at end of file diff --git a/src/urdb.cpp b/src/urdb.cpp index 2ca8d7fc3..627a5c8e6 100644 --- a/src/urdb.cpp +++ b/src/urdb.cpp @@ -356,6 +356,8 @@ bool OpenEI::QueryUtilityCompaniesbyZipcode(const wxString &zipcode, wxArrayStri bool OpenEI::QueryUtilityRates(const wxString &name, std::vector &rates, wxString *err) { + rates.clear(); // reset rates list + wxString utlnm = name; utlnm.Replace("&", "%26"); @@ -366,12 +368,6 @@ bool OpenEI::QueryUtilityRates(const wxString &name, std::vector &rate wxString url; wxString json_data; - /* - wxJSONReader reader; - wxJSONValue root; - wxJSONValue item_list; - wxJSONValue items; - */ // initial query to get first 500 rates // OpenEI International Utility Rate Database https://openei.org/services/doc/rest/util_rates/?version=7 @@ -384,102 +380,86 @@ bool OpenEI::QueryUtilityRates(const wxString &name, std::vector &rate url.Replace("", ""); url.Replace("", wxString(sam_api_key)); - json_data = MyGet(url); - if (json_data.IsEmpty()) - { - if (err) *err = "Web API call to urdb_rates returned empty JSON for utility company name = " + name; // do not report url because it has private API key - return false; - } -// change from UTF8 to UTF16 encoding to address unicode characters per SAM GitHub issue 1848 - rapidjson::GenericDocument < rapidjson::UTF16<> > reader; - reader.Parse(json_data.c_str()); - if (reader.HasParseError()) - { - if (err) *err = wxString::Format("Could not parse JSON for utility company name = %s.\nRapidJSON ParseErrorCode = %d", name, reader.GetParseError()); - return false; - } - if (reader.HasMember(L"items")) { - if (reader[L"items"].IsArray()) { + // change from UTF8 to UTF16 encoding to address unicode characters per SAM GitHub issue 1848 + rapidjson::GenericDocument < rapidjson::UTF16<> > reader; + bool retrieve_rates = true; + bool ret = true; + // up to maxlimit rates added to rates vector - auto item_list = reader[L"items"].GetArray(); + while (retrieve_rates && ret) { - rates.clear(); - // download additional rates, up to 500 at a time - old_offset = offset; - offset = max_limit + 1; - count = item_list.Size(); + json_data = MyGet(url); + if (json_data.IsEmpty()) { + if (err) *err = "Web API call to urdb_rates returned empty JSON for utility company name = " + name; // do not report url because it has private API key + ret = false; + } + else { + reader.Parse(json_data.c_str()); - if (count == 0) { + if (reader.HasParseError()) { + if (err) *err = wxString::Format("Could not parse JSON for utility company name = %s.\nRapidJSON ParseErrorCode = %d", name, reader.GetParseError()); + ret = false; + } + else if (!reader.HasMember(L"items")) { + if (err) *err = "No rates found for utility company name = " + name; + ret = false; + } + else if (!reader[L"items"].IsArray()) { if (err) *err = "No rates found for utility company name = " + name; - return false; + ret = false; } + else { + auto item_list = reader[L"items"].GetArray(); - while (count != 0) - { - url.Replace(wxString::Format("&offset=%d", (int)old_offset), wxString::Format("&offset=%d", (int)offset)); - json_data = MyGet(url); - reader.Parse(json_data.c_str()); - if (reader.HasParseError()) { - if (err) *err = wxString::Format("No rates found for url = %s\nRapidJSON ParseErrorCode = %d", url, reader.GetParseError()); - return false; + count = item_list.Size(); + + if (count == 0) { + if (err) *err = "No rates found for utility company name = " + name; + ret = false; } - if (reader.HasMember(L"items")) { - if (reader[L"items"].IsArray()) { - auto items = reader[L"items"].GetArray(); - count = items.Size(); - for (int i = 0; i < count; i++) { - item_list[i + offset] = items[i]; - } - old_offset = offset; - offset += max_limit; + else { + // add to rates vector + for (int i = 0; i < count; i++) { + RateInfo x; + x.GUID = item_list[i][L"label"].GetString(); + x.Name = item_list[i][L"name"].GetString(); + x.Utility = item_list[i][L"utility"].GetString(); + // optional + if (item_list[i].HasMember(L"sector")) + x.Sector = item_list[i][L"sector"].GetString(); + // optional + if (item_list[i].HasMember(L"description")) + x.Description = item_list[i][L"description"].GetString(); + // optional + if (item_list[i].HasMember(L"source")) + x.Source = item_list[i][L"source"].GetString(); + // optional + if (item_list[i].HasMember(L"version")) + x.Version = item_list[i][L"version"].GetInt(); + x.uri = item_list[i][L"uri"].GetString(); + // optional + if (item_list[i].HasMember(L"startdate")) + x.StartDate = GetDate(item_list[i][L"startdate"].GetInt()); + // optional + if (item_list[i].HasMember(L"enddate")) + x.EndDate = GetDate(item_list[i][L"enddate"].GetInt()); + else + x.EndDate = "N/A"; + rates.push_back(x); } + // update offset and url + old_offset = offset; + offset += max_limit; + + url.Replace(wxString::Format("&offset=%d", (int)old_offset), wxString::Format("&offset=%d", (int)offset)); + retrieve_rates = (count == max_limit); // more rates to be returned } } - // can check each for validity - count = item_list.Size(); - for (size_t i = 0; i < count; i++) { - RateInfo x; - x.GUID = item_list[i][L"label"].GetString(); - x.Name = item_list[i][L"name"].GetString(); - x.Utility = item_list[i][L"utility"].GetString(); - x.Sector = item_list[i][L"sector"].GetString(); - // optional - if (item_list[i].HasMember(L"description")) - x.Description = item_list[i][L"description"].GetString(); - // optional - if (item_list[i].HasMember(L"source")) - x.Source = item_list[i][L"source"].GetString(); - // optional - if (item_list[i].HasMember(L"version")) - x.Version = item_list[i][L"version"].GetInt(); - x.uri = item_list[i][L"uri"].GetString(); - // optional - if (item_list[i].HasMember(L"startdate")) - x.StartDate = GetDate(item_list[i][L"startdate"].GetInt()); - // optional - if (item_list[i].HasMember(L"enddate")) - x.EndDate = GetDate(item_list[i][L"enddate"].GetInt()); - else - x.EndDate = "N/A"; - rates.push_back(x); - } - - if (err) *err = wxEmptyString; - - return true; - } - else { - if (err) *err = "No rates found for utility company name = " + name; - return false; } } - else { - if (err) *err = "No rates found for utility company name = " + name; - return false; - } - + return ret; } bool OpenEI::RetrieveUtilityRateData(const wxString &guid, RateData &rate, wxString *json_url, wxString *err) @@ -1302,6 +1282,7 @@ void OpenEIUtilityRateDialog::QueryRates(const wxString &utility_name) wxBusyInfo busy("Getting available rates...", this); lblStatus->SetLabel("Loading rates..."); + mUtilityRates.clear(); wxString err; // get rates