diff --git a/ipmd/static/ipmd/js/ipmdlib.js b/ipmd/static/ipmd/js/ipmdlib.js
index 052fcdad141eedbf98fe91c68f18ffa7e4075315..1637f2bd54d6bd2f146e958834738dd15438ee9f 100644
--- a/ipmd/static/ipmd/js/ipmdlib.js
+++ b/ipmd/static/ipmd/js/ipmdlib.js
@@ -40,10 +40,27 @@ async function getModelInputSchema(dssId,modelId) {
     return await response.json();
 }
 
-async function getWeatherDatasource(weatherDatasourceId)
+/*async function getWeatherDatasource(weatherDatasourceId)
 {
     const response = await fetch(ipmdWeatherApiURL + "rest/weatherdatasource/" + weatherDatasourceId);
     return await response.json();
+}*/
+
+function getWeatherDatasourceEndpoint(weatherDatasource)
+{
+    return weatherDatasource.endpoint.replace("{WEATHER_API_URL}",ipmdWeatherApiURL);
+}
+
+function getWeatherDatasource(weatherDatasources, weatherDatasourceId)
+{
+    for(let i=0;i<weatherDatasources.length;i++)
+    {
+        if(weatherDatasources[i].id == weatherDatasourceId)
+        {
+            return weatherDatasources[i];
+        }
+    }
+    return null;
 }
 
 async function getWeatherDatasources()
@@ -61,10 +78,22 @@ function getWeatherStationList(weatherDatasource){
         let station = {"id":feature.id, "name":feature.properties.name}
         stationList.push(station);
     }
+    stationList.sort((a, b) => {
+        return (a.name < b.name) ? -1 : (a.name > b.name) ?  1 : 0;
+    });
     return stationList;
 }
 
-async function getLocationWeatherData(endpoint, weatherStationId, parameters, interval, dateStart, dateEnd){
+function renderWeatherStationSelectList(stationList, selectList){
+
+    selectList.add(new Option("-- Please select weather station --", -1));
+    for(let i=0;i<stationList.length; i++)
+    {
+        selectList.add(new Option(stationList[i].name, stationList[i].id));
+    }
+}
+
+async function getStationWeatherData(endpoint, weatherStationId, parameters, interval, dateStart, dateEnd){
     const response = await fetch(endpoint 
         + "?timeStart="        + dateStart
         + "&timeEnd="          + dateEnd
@@ -75,6 +104,18 @@ async function getLocationWeatherData(endpoint, weatherStationId, parameters, in
     return await response.json();
 }
 
+async function getLocationWeatherData(endpoint, longitude, latitude, parameters, interval, dateStart, dateEnd){
+    const response = await fetch(endpoint 
+        + "?timeStart="        + dateStart
+        + "&timeEnd="          + dateEnd
+        + "&interval="         + interval
+        + "&longitude="        + longitude
+        + "&latitude="         + latitude
+        + "&parameters=" + parameters.join(",")
+        );
+    return await response.json();
+}
+
 async function runModel(endpoint, inputData)
 {
     const response = await fetch(endpoint, {
@@ -112,6 +153,71 @@ function getWeatherParameter(weatherParameterId){
     return null;
 }
 
+function getWeatherStationCoordinate(weatherDatasource, weatherStationId)
+{
+    geoJson = JSON.parse(weatherDatasource.spatial.geoJSON);
+    let stationList = [];
+    for(let i=0;i<geoJson.features.length;i++)
+    {
+        let feature = geoJson.features[i];
+        if(feature.id == weatherStationId)
+        {
+            // TODO: Don't assume feature is a point
+            return feature.geometry.coordinates;
+        }
+    }
+
+    return null;
+}
+
+function getPragmaticWeatherParameterList(requestedParameters, availableParameters)
+{
+    let completeList = [];
+    for(let i=0;i<requestedParameters.length;i++)
+    {
+        completeList = completeList.concat(requestedParameters[i], fallbackParams[requestedParameters[i]]);
+    }
+    console.info(completeList);
+    console.info(availableParameters);
+
+    return completeList.filter(param => availableParameters.includes(param));
+
+}
+
+/**
+ * Merges the two datasets. Keeping the primaryData if both sets have data for same time and parameter
+ * If a merge operation is not possible, primaryData is returned unchanged
+ * @param {Object} primaryData 
+ * @param {Object} secondaryData 
+ */
+function mergeWeatherData(primaryData, secondaryData)
+{
+
+    // Where to start in primaryData?
+    let mergedData = {
+        timeStart: null,
+        timeEnd: null,
+        interval: primaryData.interval,
+        weatherParameters: primaryData.weatherParameters
+    };
+
+    console.info("primaryData.timeStart=" + primaryData.timeStart);
+    console.info("mergedData.timeStart=" + mergedData.timeStart);
+        
+}
+
+const fallbackParams = {
+        1001: [1002],
+        1002: [1001],
+        3001: [3002],
+        3002: [3001],
+        4002: [4003,4012,4013],
+        4003: [4002,4013,4012],
+        4012: [4013,4002,4003],
+        4013: [4012,4003,4002]
+}
+
+
 const weatherParameterList = [
     {
         "id": 1001,
diff --git a/ipmd/templates/ipmd/saddlegallmidgeform.html b/ipmd/templates/ipmd/saddlegallmidgeform.html
index 6692467ee82e1486e91f55893e0cf0e3874a8dee..3985488860c6b58433e160d386abc42510d64f8b 100644
--- a/ipmd/templates/ipmd/saddlegallmidgeform.html
+++ b/ipmd/templates/ipmd/saddlegallmidgeform.html
@@ -27,10 +27,32 @@
 <div class="singleBlockContainer">
 	<h1>{% trans "Saddle gall midge" %}</h1>
     <div id="inputForm"></div>
-    <div id="weatherStations" style="display: none;">
-    <h2>Weather stations</h2>
-    <select class="form-control" name="weatherStationId" id="weatherStationId"></select>
-    </div>
+    <div id="weatherDataForm" style="display: none;">
+    <h2>Weather data</h2>
+    <fieldset id="historicDatasourceFields">
+        <legend>Weather datasource (historic)</legend>
+        <select class="form-control" name="weatherDatasourceId" id="weatherDatasourceList" onchange="handleWeatherDatasourceSelected(this);"></select>
+        <div id="historicSourceInfo" style="display: none;"></div>
+    </fieldset>
+    <fieldset id="stationFields" style="display: none;">
+        <select class="form-control" name="weatherStationId" id="weatherStationId" onchange="handleWeatherStationSelected(this);" ></select>
+    </fieldset>
+    <fieldset id="locationFields">
+        <legend>Location (decimal degrees)</legend>
+        <div class="form-group">
+            <label for="latitude">Latitude</label>
+            <input type="number" class="form-control" id="latitude" name="latitude" placeholder="Latitude">
+        </div>
+        <div class="form-group">
+            <label for="longitude">Longitude</label>
+            <input type="number" class="form-control" id="longitude" name="longitude" placeholder="Longitude">
+        </div>
+    </fieldset>
+    <fieldset id="forecastDatasourceFields">
+        <legend>Weather forecasts datasource</legend>
+        <select class="form-control" name="forecastWeatherDatasourceId" id="forecastWeatherDatasourceList" onchange="handleForecastSourceSelected(this);"></select>
+        <div id="forecastSourceInfo" style="display: none;"></div>
+    </fieldset>
     <button class="btn btn-primary" type="button" onclick="submitData();">Submit</button>
     <div style="aspect-ratio: 2;">
         <canvas id="resultChart""></canvas>
@@ -49,13 +71,14 @@
 <script type="text/javascript">
     // Page globals
     var modelMetaData = undefined;
-    var weatherDatasource = undefined;
+    var currentWeatherDatasource = undefined;
+    var currentForecastWeatherDatasource = undefined;
     var weatherDatasources = undefined;
     var editor = undefined;
-    const selectList = document.getElementById("weatherStationId");
-
+    var selectList = document.getElementById("weatherStationId");
+    
     var weatherData = undefined;
-
+    
     async function initPage() {
         modelMetaData = await getModelMetadata("adas.dss","HAPDMA");
         document.getElementById("modelDescription").innerHTML= await modelMetaData["description"];
@@ -71,32 +94,90 @@
         let fullSchema = JSON.parse(modelMetaData["execution"]["input_schema"]);
         if(fullSchema["properties"]["weatherData"] !== undefined)
         {
-            //console.info("Adding weather stations");
-            // Pull weather stations from web service, render list
-            weatherDatasource = await getWeatherDatasource("no.nibio.lmt");
+
+            // Pull weather data sources from web service, render lists (historic and forecast sources, some are both)
             weatherDatasources = await getWeatherDatasources();
             console.info(weatherDatasources);
-            stationList = await getWeatherStationList(weatherDatasource);
-            stationList.sort((a, b) => {
+            weatherDatasources.sort((a, b) => {
                 return (a.name < b.name) ? -1 : (a.name > b.name) ?  1 : 0;
             });
-            
-            for(let i=0;i<stationList.length; i++)
+            let weatherDatasourceList = document.getElementById("weatherDatasourceList");
+            weatherDatasourceList.add(new Option("Please select a weather datasource", "-1"));
+            for(let i=0;i<weatherDatasources.length; i++)
             {
-                selectList.add(new Option(stationList[i].name, stationList[i].id))
+                if(weatherDatasources[i].temporal.historic != null && weatherDatasources[i].temporal.historic.start != null)
+                {
+                    weatherDatasourceList.add(new Option(weatherDatasources[i].name, weatherDatasources[i].id));
+                }
+            }
+            let forecastWeatherDatasourceList = document.getElementById("forecastWeatherDatasourceList");
+            forecastWeatherDatasourceList.add(new Option("Please select a weather forecast datasource", "-1"));
+            for(let i=0;i<weatherDatasources.length; i++)
+            {
+                if(weatherDatasources[i].temporal.forecast != null && weatherDatasources[i].temporal.forecast > 0)
+                {
+                    forecastWeatherDatasourceList.add(new Option(weatherDatasources[i].name, weatherDatasources[i].id));
+                }
             }
-            document.getElementById("weatherStations").style.display = "block";
-            console.info(weatherDatasource);
+            
+            document.getElementById("weatherDataForm").style.display = "block";
+            
         }
 
         // TODO: Remove this auto-mock!!
         editor.getValue().optionalData.startDate="2023-08-01";
         editor.getValue().optionalData.endDate="2023-08-10";
-        submitData();
+        document.getElementById("longitude").value="11.781989";
+        document.getElementById("latitude").value="59.680468";
+        //submitData();
     }
 
     initPage();
 
+    function handleWeatherDatasourceSelected(weatherDatasourceList){
+        currentWeatherDatasource = getWeatherDatasource(
+            weatherDatasources, 
+            weatherDatasourceList.options[weatherDatasourceList.selectedIndex].value
+            );
+        let sourceInfo = document.getElementById("historicSourceInfo");
+        sourceInfo.innerHTML = currentWeatherDatasource.description;
+        sourceInfo.style.display="block";
+        if(currentWeatherDatasource.access_type == "stations")
+        {
+            // Display the weather stations
+            renderWeatherStationSelectList(getWeatherStationList(currentWeatherDatasource), selectList);
+            document.getElementById("stationFields").style.display = "block";
+        }
+        else
+        {
+            // Location based API
+            // Display lat/lon input fields
+            document.getElementById("stationFields").style.display = "none";
+            // TODO: Add map?
+
+        }
+        console.info(currentWeatherDatasource);
+    }
+
+    function handleForecastSourceSelected(forecastSourceSelectList)
+    {
+        currentForecastWeatherDatasource = getWeatherDatasource(
+            weatherDatasources, 
+            forecastWeatherDatasourceList.options[forecastWeatherDatasourceList.selectedIndex].value
+            );
+        let sourceInfo = document.getElementById("historicSourceInfo");
+        sourceInfo.innerHTML = currentWeatherDatasource.description;
+        sourceInfo.style.display="block";
+    }
+
+    function handleWeatherStationSelected(weatherStationSelectList)
+    {
+        let weatherStationId = selectList.options[selectList.selectedIndex].value;
+        let stationCoordinate = getWeatherStationCoordinate(currentWeatherDatasource, weatherStationId);
+        console.info(stationCoordinate);
+        document.getElementById("longitude").value = stationCoordinate[0];
+        document.getElementById("latitude").value = stationCoordinate[1];
+    }
 
     async function submitData(){
         console.info("submitData!");
@@ -115,24 +196,92 @@
         if(fullSchema["properties"]["weatherData"] !== undefined)
         {
             console.info("Need to get weather data!");
-            let weatherStationId = selectList.options[selectList.selectedIndex].value;
+            let forecastData = undefined;
+            // 1. Historic weather data
+            if(currentWeatherDatasource != undefined)
+            {
+                if(currentWeatherDatasource.access_type == "stations")
+                {
+                    let weatherStationId = selectList.options[selectList.selectedIndex].value;
 
-            weatherData = await getLocationWeatherData(
-                weatherDatasource.endpoint,
-                weatherStationId,
-                (function (){
-                    let parameterList = []
-                    modelMetaData.input.weather_parameters.forEach(function(weatherParameter){
-                        parameterList.push(weatherParameter.parameter_code)
-                    })
-                    return parameterList;
-                }()),
-                3600,
-                inputData.optionalData.startDate,
-                inputData.optionalData.endDate,
-            );
+                    weatherData = await getStationWeatherData(
+                        getWeatherDatasourceEndpoint(currentWeatherDatasource),
+                        weatherStationId,
+                        getPragmaticWeatherParameterList(
+                            function (){
+                                let parameterList = []
+                                modelMetaData.input.weather_parameters.forEach(function(weatherParameter){
+                                    parameterList.push(weatherParameter.parameter_code)
+                                })
+                                return parameterList;
+                            }(),
+                            currentWeatherDatasource.parameters.common
+                        ),
+                        3600,
+                        inputData.optionalData.startDate,
+                        inputData.optionalData.endDate,
+                    );
+                    
+                }
+                else
+                {
+                    weatherData = await getLocationWeatherData(
+                        getWeatherDatasourceEndpoint(currentWeatherDatasource),
+                        document.getElementById("longitude").value,
+                        document.getElementById("latitude").value,
+                        getPragmaticWeatherParameterList(
+                            function (){
+                                let parameterList = []
+                                modelMetaData.input.weather_parameters.forEach(function(weatherParameter){
+                                    parameterList.push(weatherParameter.parameter_code)
+                                })
+                                return parameterList;
+                            }(),
+                            currentWeatherDatasource.parameters.common
+                        ),
+                        3600,
+                        inputData.optionalData.startDate,
+                        inputData.optionalData.endDate,
+                    );
+                }
+            }
+
+            // 2. Forecast weather data
+            if(currentForecastWeatherDatasource != undefined)
+            {
+                forecastData = await getLocationWeatherData(
+                        getWeatherDatasourceEndpoint(currentForecastWeatherDatasource),
+                        document.getElementById("longitude").value,
+                        document.getElementById("latitude").value,
+                        getPragmaticWeatherParameterList(
+                            function (){
+                                let parameterList = []
+                                modelMetaData.input.weather_parameters.forEach(function(weatherParameter){
+                                    parameterList.push(weatherParameter.parameter_code)
+                                })
+                                return parameterList;
+                            }(),
+                            currentForecastWeatherDatasource.parameters.common
+                        ),
+                        3600,
+                        inputData.optionalData.startDate,
+                        inputData.optionalData.endDate,
+                    );
+                // Merge if both historic and forecast data have been collected
+                if(weatherData == undefined)
+                {
+                    weatherData = forecastData;
+                }
+                else
+                {
+                    // Is NULL until method is implemented
+                    weatherData = mergeWeatherData(weatherData, forecastData);
+                }
+            }
+
+            
             inputData["weatherData"] = weatherData;
-            console.info(weatherData);
+                //console.info(weatherData);
         }
         // Ready to call server?
         //console.info(JSON.stringify(inputData));
@@ -204,6 +353,8 @@
 
     }
 
+    
+
     // Mock result!!! Waiting for ADAS to fix CORS issue
     const mockResult={
         "timeStart": "2023-06-30T22:00:00+00:00",