/* ================================================================== * EnaSolarXMLDatumDataSourceTest.java - Oct 2, 2011 9:24:34 PM * * Copyright 2007-2011 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 * ================================================================== */ package net.solarnetwork.node.power.enasolar.ws.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.Calendar; import java.util.LinkedHashMap; import java.util.Map; import net.solarnetwork.node.domain.GeneralNodePVEnergyDatum; import net.solarnetwork.node.power.enasolar.ws.EnaSolarXMLDatumDataSource; import net.solarnetwork.node.test.AbstractNodeTest; import org.junit.Test; /** * Test case for the {@link EnaSolarXMLDatumDataSource} class. * * @author matt * @version 1.2 */ public class EnaSolarXMLDatumDataSourceTest extends AbstractNodeTest { @Test public void parseDeviceInfoDatum() { EnaSolarXMLDatumDataSource dataSource = new EnaSolarXMLDatumDataSource(); dataSource.setUrl(getClass().getResource("deviceinfo.xml").toString()); dataSource.init(); Map<String, String> deviceInfoMap = new LinkedHashMap<String, String>(10); deviceInfoMap.put("outputVoltage", "//data[@key='acOutputVolts']/@value"); deviceInfoMap.put("outputPower", "//data[@key='acPower']/@value"); deviceInfoMap.put("decaWattHoursTotal", "//data[@key='decaWattHoursTotal']/@value"); deviceInfoMap.put("inputVoltage", "//data[@key='pvVolts']/@value"); deviceInfoMap.put("inputPower", "//data[@key='pvPower']/@value"); dataSource.setXpathMap(deviceInfoMap); GeneralNodePVEnergyDatum datum = dataSource.readCurrentDatum(); log.debug("Got datum: {}", datum); assertEquals(Long.valueOf(57540), datum.getWattHourReading()); assertEquals(Integer.valueOf(628), datum.getWatts()); assertNotNull(datum.getVoltage()); assertEquals(241.1, datum.getVoltage().floatValue(), 0.01); assertNotNull(datum.getDCPower()); assertEquals(Integer.valueOf(681), datum.getDCPower()); assertNotNull(datum.getDCVoltage()); assertEquals(304.3F, datum.getDCVoltage().floatValue(), 0.01); } @Test public void parseDeviceInfoDatumAcrossDays() { EnaSolarXMLDatumDataSource dataSource = new EnaSolarXMLDatumDataSource(); dataSource.setSampleCacheMs(0); // disable cache dataSource.setUrl(getClass().getResource("deviceinfo-daily-resetting.xml").toString()); dataSource.init(); Map<String, String> deviceInfoMap = new LinkedHashMap<String, String>(10); deviceInfoMap.put("outputVoltage", "//data[@key='acOutputVolts']/@value"); deviceInfoMap.put("outputPower", "//data[@key='acPower']/@value"); deviceInfoMap.put("kWattHoursToday", "//data[@key='kWattHoursToday']/@value"); deviceInfoMap.put("inputVoltage", "//data[@key='pvVolts']/@value"); deviceInfoMap.put("inputPower", "//data[@key='pvPower']/@value"); dataSource.setXpathMap(deviceInfoMap); GeneralNodePVEnergyDatum datum = dataSource.readCurrentDatum(); log.debug("Got datum: {}", datum); assertEquals(Integer.valueOf(628), datum.getWatts()); assertEquals(Long.valueOf(17940), datum.getWattHourReading()); // read in zero-watt reading, for threshold dataSource.setUrl(getClass().getResource("deviceinfo-dayend.xml").toString()); for ( int i = 0; i < (int) EnaSolarXMLDatumDataSource.ZERO_WATT_THRESHOLD; i++ ) { datum = dataSource.readCurrentDatum(); assertNotNull("Day end datum " + i, datum); assertEquals(Integer.valueOf(0), datum.getWatts()); assertEquals(Long.valueOf(17940), datum.getWattHourReading()); } for ( int i = 0; i < 5; i++ ) { GeneralNodePVEnergyDatum invalidDatum = dataSource.readCurrentDatum(); assertNull(invalidDatum); } // now trick the data source into being the next day; we are changing the cached sample's creation date // to yesterday Calendar c = Calendar.getInstance(); c.setTime(datum.getCreated()); c.add(Calendar.DATE, -1); datum.setCreated(c.getTime()); dataSource.setUrl(getClass().getResource("deviceinfo-daystart.xml").toString()); for ( int i = 0; i < 5; i++ ) { GeneralNodePVEnergyDatum nextDayDatum = dataSource.readCurrentDatum(); assertNull(nextDayDatum); } dataSource.setUrl(getClass().getResource("deviceinfo-daily-resetting.xml").toString()); datum = dataSource.readCurrentDatum(); assertEquals(Integer.valueOf(628), datum.getWatts()); assertEquals(Long.valueOf(17940), datum.getWattHourReading()); } @Test public void parseDeviceInfoDatumWithTemporaryOutage() { EnaSolarXMLDatumDataSource dataSource = new EnaSolarXMLDatumDataSource(); dataSource.setSampleCacheMs(0); // disable cache dataSource.setUrl(getClass().getResource("deviceinfo.xml").toString()); dataSource.init(); Map<String, String> deviceInfoMap = new LinkedHashMap<String, String>(10); deviceInfoMap.put("outputVoltage", "//data[@key='acOutputVolts']/@value"); deviceInfoMap.put("outputPower", "//data[@key='acPower']/@value"); deviceInfoMap.put("decaWattHoursTotal", "//data[@key='decaWattHoursTotal']/@value"); deviceInfoMap.put("inputVoltage", "//data[@key='pvVolts']/@value"); deviceInfoMap.put("inputPower", "//data[@key='pvPower']/@value"); dataSource.setXpathMap(deviceInfoMap); GeneralNodePVEnergyDatum datum = dataSource.readCurrentDatum(); log.debug("Got datum: {}", datum); assertEquals(Integer.valueOf(628), datum.getWatts()); assertEquals(Long.valueOf(57540), datum.getWattHourReading()); // read in a few zero-watt reading, (less than) threshold times, i.e. inverter power went out dataSource.setUrl(getClass().getResource("deviceinfo-daystart.xml").toString()); for ( int i = 0; i < 5; i++ ) { GeneralNodePVEnergyDatum invalidDatum = dataSource.readCurrentDatum(); assertNull(invalidDatum); } // power comes back on, and readings go back to normal dataSource.setUrl(getClass().getResource("deviceinfo.xml").toString()); datum = dataSource.readCurrentDatum(); assertEquals(Integer.valueOf(628), datum.getWatts()); assertEquals(Long.valueOf(57540), datum.getWattHourReading()); } @Test public void parseMetersDataDatum() { EnaSolarXMLDatumDataSource dataSource = new EnaSolarXMLDatumDataSource(); dataSource.setUrls(new String[] { getClass().getResource("data.xml").toString(), getClass().getResource("meters.xml").toString() }); dataSource.init(); Map<String, String> deviceInfoMap = new LinkedHashMap<String, String>(10); deviceInfoMap.put("outputPower", "//OutputPower"); deviceInfoMap.put("outputVoltage", "//OutputVoltage"); deviceInfoMap.put("inputVoltage", "//InputVoltage"); deviceInfoMap.put("energyLifetime", "//EnergyLifetime"); dataSource.setXpathMap(deviceInfoMap); GeneralNodePVEnergyDatum datum = dataSource.readCurrentDatum(); log.debug("Got datum: {}", datum); assertEquals(Integer.valueOf(214), datum.getWatts()); assertEquals(Long.valueOf(7629660), datum.getWattHourReading()); assertNotNull(datum.getVoltage()); assertEquals(237.2F, datum.getVoltage().floatValue(), 0.01); assertNotNull(datum.getDCVoltage()); assertEquals(419.3F, datum.getDCVoltage().floatValue(), 0.01); } @Test public void noRouteToHostException() { EnaSolarXMLDatumDataSource dataSource = new EnaSolarXMLDatumDataSource(); dataSource .setUrls(new String[] { "http://192.168.9.1/data.xml", "http://192.168.9.1/meters.xml" }); dataSource.init(); String s = dataSource.getInfoMessage(); assertNotNull(s); assertTrue(s.startsWith("Error communicating with EnaSolar inverter:")); } }