net.solarnetwork.node.power.impl.XantrexGtViewPowerDatumDataSource.java Source code

Java tutorial

Introduction

Here is the source code for net.solarnetwork.node.power.impl.XantrexGtViewPowerDatumDataSource.java

Source

/* ===================================================================
 * XantrexGtViewPowerDatumDataSource.java
 * 
 * Created Aug 7, 2008 9:48:26 PM
 * 
 * Copyright (c) 2008 Solarnetwork.net Dev Team.
 * 
 * This program is free software; you can redistribute it and/or 
 * modify it under the terms of the GNU General Public License as 
 * published by the Free Software Foundation; either version 2 of 
 * the License, or (at your option) any later version.
 * 
 * This program 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 GNU 
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License 
 * along with this program; if not, write to the Free Software 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
 * 02111-1307 USA
 * ===================================================================
 */

/* ==================================================================
 * UrlDataCollector.java - Dec 9, 2009 9:46:41 AM
 * 
 * Copyright 2007-2009 SolarNetwork.net Dev Team
 * 
 * This program is free software; you can redistribute it and/or 
 * modify it under the terms of the GNU General Public License as 
 * published by the Free Software Foundation; either version 2 of 
 * the License, or (at your option) any later version.
 * 
 * This program 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 GNU 
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License 
 * along with this program; if not, write to the Free Software 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
 * 02111-1307 USA
 * ==================================================================
 * $Id$
 * ==================================================================
 */

package net.solarnetwork.node.power.impl;

import net.solarnetwork.node.DataCollector;
import net.solarnetwork.node.DatumDataSource;
import net.solarnetwork.node.power.PowerDatum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectFactory;

/**
 * Implementation of {@link GenerationDataSource} for the Xantrex series of
 * inverters, acquiring the data by reading the files written by the freeware
 * GT-View application.
 * 
 * <p>
 * It assumes the {@link DataCollector} implementation blocks until appropriate
 * data is available when the {@link DataCollector#collectData()} method is
 * called.
 * </p>
 * 
 * <p>
 * The configurable properties of this class are:
 * </p>
 * 
 * <dl class="class-properties">
 * <dt>dataCollectorFactory</dt>
 * <dd>The factory for creating {@link DataCollector} instances with.
 * {@link GenericObjectFactory#getObject()} will be called on each invocation of
 * {@link #readCurrentConsumptionDatum()}.</dd>
 * </dl>
 * 
 * @author matt, mike
 * @version 1.2
 */
public class XantrexGtViewPowerDatumDataSource implements DatumDataSource<PowerDatum> {

    private static final int FRAME_IDX_PV_VOLTS = 2;
    private static final int FRAME_IDX_PV_AMPS = 3;
    private static final int FRAME_IDX_PV_WATTS = 5;
    private static final int FRAME_IDX_AC_WATTS = 6;
    private static final int FRAME_IDX_AC_VOLTS = 8;
    private static final int FRAME_IDX_WH = 9;

    private final Logger log = LoggerFactory.getLogger(getClass());

    private ObjectFactory<DataCollector> dataCollectorFactory;

    @Override
    public String getUID() {
        return getClass().getName();
    }

    @Override
    public String getGroupUID() {
        return null;
    }

    @Override
    public Class<? extends PowerDatum> getDatumType() {
        return PowerDatum.class;
    }

    @Override
    public PowerDatum readCurrentDatum() {
        DataCollector dataCollector = null;
        String data = null;
        try {
            dataCollector = this.dataCollectorFactory.getObject();
            dataCollector.collectData();
            data = dataCollector.getCollectedDataAsString();
        } finally {
            if (dataCollector != null) {
                dataCollector.stopCollecting();
            }
        }

        if (data == null) {
            log.warn("Null serial data received, serial communications problem");
            return null;
        }

        return getPowerDatumInstance(data);

    }

    @SuppressWarnings("deprecation")
    private PowerDatum getPowerDatumInstance(String data) {
        if (log.isDebugEnabled()) {
            log.debug("Raw last sample data in file: " + data);
        }

        String[] tokens = data.split("\t");

        // only use this if DC watts is non-zero. Some junk is
        // left over from previous day in other fields
        Double d = getFrameDouble(tokens, FRAME_IDX_PV_WATTS);

        if (d == null || d.doubleValue() == 0.0) {
            return null;
        }

        PowerDatum datum = new PowerDatum();

        // Field 0: Date: unused

        // Field 1: Time: unused

        // Field 2: DC Volts
        d = getFrameDouble(tokens, FRAME_IDX_PV_VOLTS);
        if (d != null) {
            datum.setPvVolts(d.floatValue());
            if (log.isDebugEnabled()) {
                log.debug("DC Volts: " + d);
            }
        }

        // Field 3: DC Amps
        d = getFrameDouble(tokens, FRAME_IDX_PV_AMPS);
        if (d != null) {
            datum.setPvAmps(d.floatValue());
            if (log.isDebugEnabled()) {
                log.debug("DC Amps: " + d);
            }
        }

        // Field 4: MPPT: unused

        // Field 5: DC Watts: already parsed above

        // Field 7: Efficiency: unused

        // Field 8: AC Volts: unused
        d = getFrameDouble(tokens, FRAME_IDX_AC_VOLTS);
        if (d != null) {
            datum.setAcOutputVolts(d.floatValue());
            if (log.isDebugEnabled()) {
                log.debug("AC Volts: " + d);
            }
        }

        // Field 6: AC Watts: used to set AC amps
        d = getFrameDouble(tokens, FRAME_IDX_AC_WATTS);
        if (d != null) {
            if (datum.getAcOutputVolts() > 0) {
                datum.setAcOutputAmps(d.floatValue() / datum.getAcOutputVolts());
            }
            if (log.isDebugEnabled()) {
                log.debug("AC Amps: " + d);
            }
        }

        // Field 9: Cumulative AC Watts
        d = getFrameDouble(tokens, FRAME_IDX_WH);
        if (d != null) {
            // store Wh as kWh
            datum.setKWattHoursToday(d.doubleValue() / 1000);
            if (log.isDebugEnabled()) {
                log.debug("WH: " + d);
            }
        }

        return datum;

    }

    private Double getFrameDouble(String[] frame, int idx) {
        if (frame[idx].length() > 0) {
            return Double.valueOf(frame[idx]);
        }
        return null;
    }

    public ObjectFactory<DataCollector> getDataCollectorFactory() {
        return dataCollectorFactory;
    }

    public void setDataCollectorFactory(ObjectFactory<DataCollector> dataCollectorFactory) {
        this.dataCollectorFactory = dataCollectorFactory;
    }

}