Skip to content
Snippets Groups Projects
ALabDataParser.java 6.50 KiB
/*
 * Copyright (c) 2015 NIBIO <http://www.nibio.no/>. 
 * 
 * This file is part of VIPSLogic.
 * VIPSLogic is free software: you can redistribute it and/or modify
 * it under the terms of the NIBIO Open Source License as published by 
 * NIBIO, either version 1 of the License, or (at your option) any
 * later version.
 * 
 * VIPSLogic is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * NIBIO Open Source License for more details.
 * 
 * You should have received a copy of the NIBIO Open Source License
 * along with VIPSLogic.  If not, see <http://www.nibio.no/licenses/>.
 * 
 */

package no.nibio.vips.util.weather;

import java.io.IOException;
import java.net.URL;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import no.nibio.vips.entity.WeatherObservation;
import no.nibio.vips.util.InvalidAggregationTypeException;
import no.nibio.vips.util.WeatherObservationListException;
import no.nibio.vips.util.WeatherUtil;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

/**
 * Reads/parses data from A-Lab weather stations
 * @copyright 2015 <a href="http://www.nibio.no/">NIBIO</a>
 * @author Tor-Einar Skog <tor-einar.skog@nibio.no>
 */
public class ALabDataParser {
    
    private static final Map<String, String> parameters;
    static {
        Map<String, String> staticMap = new HashMap<>();
        staticMap.put("119", "TM");
        staticMap.put("120", "UM");
        staticMap.put("121", "RRACC"); // Accumulated rain over an unkown amount of time!
        staticMap.put("122", "DD2"); 
        staticMap.put("123", "FF2"); 
        staticMap.put("124", "PPP"); 
        staticMap.put("125", "TJM10"); 
        staticMap.put("126", "VAN10p"); 
        parameters = Collections.unmodifiableMap(staticMap);
    }
    // 
    public final static String ALAB_URL_TEMPLATE = "http://xml.a-log.net/xml-export.cgi?devid={0}&username={1}&password={2}&measurements=all&from={3}&to={4}";
    
    public List<WeatherObservation> getWeatherObservations(String stationID, TimeZone timeZone, Date startDate, String userName, String password) throws ParseWeatherDataException 
    {
        List<WeatherObservation> retVal = new ArrayList<>();
        DateFormat timeParseFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        timeParseFormat.setTimeZone(timeZone);
        
        WeatherUtil wUtil = new WeatherUtil();
        startDate = wUtil.normalizeToExactDate(startDate, timeZone);
        Date endDate = wUtil.normalizeToExactDate(new Date(), timeZone);
        DateFormat urlDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        urlDateFormat.setTimeZone(timeZone);
        String from = urlDateFormat.format(startDate);
        String to = urlDateFormat.format(endDate);
        
        // Get the raw data from service, serialize into WeatherObservations
        Map<String, List<WeatherObservation>> serialized = new HashMap<>();
        try {
            URL aLabURL = new URL(MessageFormat.format(ALabDataParser.ALAB_URL_TEMPLATE, stationID,userName,password,from,to));
            Document doc = this.getDocument(aLabURL);
            
            // Get all measurements at 15 min intervals
            // Must aggregate afterwards
            List<Node> list = doc.selectNodes("//Measurement");
            
            for(Node node:list)
            {
                Date timeMeasured = timeParseFormat.parse(node.valueOf("@Time"));
                List<Node> valueNodes = node.selectNodes("Value");
                for(Node valueNode : valueNodes)
                {
                    WeatherObservation obs = new WeatherObservation();
                    obs.setTimeMeasured(timeMeasured);
                    obs.setElementMeasurementTypeId(ALabDataParser.parameters.get(valueNode.valueOf("@Type")));
                    // Set logInterval to 15min
                    obs.setLogIntervalId(WeatherObservation.LOG_INTERVAL_ID_15M);
                    obs.setValue(Double.valueOf(valueNode.getText()));
                    
                    if(!serialized.containsKey(obs.getElementMeasurementTypeId()))
                    {
                        serialized.put(obs.getElementMeasurementTypeId(), new ArrayList<WeatherObservation>());
                    }
                    serialized.get(obs.getElementMeasurementTypeId()).add(obs);
                    
                }
                //System.out.println(timeMeasured);
            }
        }
        catch(IOException | DocumentException | ParseException ex)
        {
            throw new ParseWeatherDataException(ex.getMessage());
        }
        
        try
        {
            // Convert from 15 min intervals to hourly intervals
            // Bear in mind that RRACC must be converted to RR
            for(String param:serialized.keySet())
            {
                List<WeatherObservation> paramObs = serialized.get(param);
                paramObs = wUtil.removeDuplicateWeatherObservations(paramObs, 0.05);
                if(!param.equals("RRACC"))
                {
                    retVal.addAll(wUtil.getAggregateHourlyValues(paramObs, timeZone, WeatherObservation.LOG_INTERVAL_ID_15M, WeatherUtil.AGGREGATION_TYPE_AVERAGE));
                }
                else
                {
                    //System.out.println("RRACC being calculated");
                    retVal.addAll(wUtil.getIncrementalValuesFromAccumulated(paramObs, timeZone, WeatherObservation.LOG_INTERVAL_ID_1H));
                }
            }
        }catch (WeatherObservationListException | InvalidAggregationTypeException ex)
        {
            throw new ParseWeatherDataException(ex.getMessage());
        }
        Collections.sort(retVal);
        
        
        return retVal;
    }
    
    private Document getDocument(URL url) throws IOException, DocumentException
    {
        //System.out.println("URL=" + url.toString());
        /*BufferedReader in = new BufferedReader(
        new InputStreamReader(url.openStream()));

        String inputLine;
        while ((inputLine = in.readLine()) != null)
        {
            System.out.println(inputLine);
        }*/
        
        Document doc = new SAXReader().read(url);
        return doc;
        
    }
}