Search in sources :

Example 1 with FragmentedPacketGroup

use of me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup in project solarthing by wildmountainfarms.

the class HomeAssistantActionNode method createAction.

@Override
public Action createAction(ActionEnvironment actionEnvironment) {
    LatestFragmentedPacketGroupEnvironment latestFragmentedPacketGroupEnvironment = actionEnvironment.getInjectEnvironment().get(LatestFragmentedPacketGroupEnvironment.class);
    return Actions.createRunOnce(() -> {
        FragmentedPacketGroup packetGroup = latestFragmentedPacketGroupEnvironment.getFragmentedPacketGroupProvider().getPacketGroup();
        if (packetGroup == null) {
            LOGGER.warn("packetGroup is null!");
            return;
        }
        List<Call<SensorInfo>> calls = new ArrayList<>();
        for (Packet packet : packetGroup.getPackets()) {
            int fragmentId = packetGroup.getFragmentId(packet);
            String sourceId = packetGroup.getSourceId(packet);
            String nameBase = "solarthing_" + sourceId + "_" + fragmentId + "_";
            if (packet instanceof FXStatusPacket) {
                FXStatusPacket fx = (FXStatusPacket) packet;
                nameBase += "fx_" + fx.getAddress() + "_";
                calls.add(service.updateSensor(nameBase + "acmode", new SensorState(fx.getACMode().getModeName(), new AttributeBuilder().friendlyName("AC Mode").build())));
                calls.add(service.updateBinarySensor(nameBase + "acpresent", new BinarySensorState(fx.getACMode() != ACMode.NO_AC, new AttributeBuilder().friendlyName("AC Present").build())));
                calls.add(service.updateSensor(nameBase + "batteryvoltage", new SensorState(FORMAT.format(fx.getBatteryVoltage()), new AttributeBuilder().friendlyName("Battery Voltage").build())));
            }
        }
        for (Call<SensorInfo> call : calls) {
            try {
                // TODO move into a separate thread
                Response<SensorInfo> response = call.execute();
                if (!response.isSuccessful()) {
                    LOGGER.error("Unsuccessful response! " + requireNonNull(response.errorBody()).string());
                }
            } catch (IOException e) {
                LOGGER.error("Home assistant error", e);
            }
        }
    });
}
Also used : FragmentedPacketGroup(me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup) Call(retrofit2.Call) Packet(me.retrodaredevil.solarthing.packets.Packet) FXStatusPacket(me.retrodaredevil.solarthing.solar.outback.fx.FXStatusPacket) AttributeBuilder(me.retrodaredevil.solarthing.homeassistant.data.AttributeBuilder) BinarySensorState(me.retrodaredevil.solarthing.homeassistant.data.BinarySensorState) BinarySensorState(me.retrodaredevil.solarthing.homeassistant.data.BinarySensorState) SensorState(me.retrodaredevil.solarthing.homeassistant.data.SensorState) ArrayList(java.util.ArrayList) IOException(java.io.IOException) LatestFragmentedPacketGroupEnvironment(me.retrodaredevil.solarthing.actions.environment.LatestFragmentedPacketGroupEnvironment) FXStatusPacket(me.retrodaredevil.solarthing.solar.outback.fx.FXStatusPacket) SensorInfo(me.retrodaredevil.solarthing.homeassistant.data.SensorInfo)

Example 2 with FragmentedPacketGroup

use of me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup in project solarthing by wildmountainfarms.

the class SolarThingGraphQLFXService method queryFXCharging.

@GraphQLQuery(description = "Gives the timer values for the master FX of a single fragment over a time range")
public List<DataNode<FXChargingPacket>> queryFXCharging(@GraphQLArgument(name = "from") long from, @GraphQLArgument(name = "to") long to, @GraphQLArgument(name = "fragmentId") int fragmentId) {
    MetaDatabase metaDatabase = simpleQueryHandler.queryMeta();
    FXChargingSettingsPacket fxChargingSettingsPacket = null;
    FXChargingTemperatureAdjustPacket fxChargingTemperatureAdjustPacket = null;
    for (TargetedMetaPacket targetedMetaPacket : metaDatabase.getMeta(to, fragmentId)) {
        if (targetedMetaPacket.getPacketType() == TargetedMetaPacketType.FX_CHARGING_SETTINGS) {
            fxChargingSettingsPacket = (FXChargingSettingsPacket) targetedMetaPacket;
        } else if (targetedMetaPacket.getPacketType() == TargetedMetaPacketType.FX_CHARGING_TEMPERATURE_ADJUST) {
            fxChargingTemperatureAdjustPacket = (FXChargingTemperatureAdjustPacket) targetedMetaPacket;
        }
    }
    if (fxChargingSettingsPacket == null) {
        throw new UnexpectedResponseException("Could not find FX Charging settings in meta!");
    }
    // 3 hours back
    long startTime = from - 3 * 60 * 60 * 1000;
    List<? extends InstancePacketGroup> packets = simpleQueryHandler.queryStatus(startTime, to, null);
    // We make masterIdIgnoreDistance null because we will only be using fragmentId as the master fragment ID
    Map<String, List<FragmentedPacketGroup>> map = // separate based on source ID
    PacketGroups.sortPackets(packets, simpleQueryHandler.getDefaultInstanceOptions(), SolarThingConstants.STANDARD_MAX_TIME_DISTANCE.toMillis(), null, // make fragmentId be the master ID
    FragmentUtil.createPriorityComparator(fragmentId));
    List<FragmentedPacketGroup> sortedPackets = null;
    for (List<FragmentedPacketGroup> fragmentedPacketGroups : map.values()) {
        if (fragmentedPacketGroups.get(0).hasFragmentId(fragmentId)) {
            sortedPackets = fragmentedPacketGroups;
            break;
        }
    }
    if (sortedPackets == null) {
        throw new UnexpectedResponseException("Could not find fragment ID: " + fragmentId);
    }
    FXChargingSettings settings = fxChargingSettingsPacket.getFXChargingSettings();
    FXChargingStateHandler stateHandler = new FXChargingStateHandler(settings);
    Long lastUpdate = null;
    List<DataNode<FXChargingPacket>> r = new ArrayList<>();
    for (FragmentedPacketGroup packetGroup : sortedPackets) {
        List<FXStatusPacket> fxPackets = new ArrayList<>();
        Integer temperature = null;
        for (Packet packet : packetGroup.getPackets()) {
            if (packet instanceof FXStatusPacket && packetGroup.getFragmentId(packet) == fragmentId) {
                fxPackets.add((FXStatusPacket) packet);
            } else if (packet instanceof BatteryTemperature) {
                temperature = Math.round(((BatteryTemperature) packet).getBatteryTemperatureCelsius().floatValue());
            }
        }
        if (fxPackets.isEmpty()) {
            continue;
        }
        if (temperature == null) {
            // we need temperature data for accurate results // TODO add option for systems that don't use temperature compensation
            continue;
        }
        temperature += fxChargingTemperatureAdjustPacket == null ? 0 : fxChargingTemperatureAdjustPacket.getTemperatureAdjustCelsius();
        FXStatusPacket fx = OutbackUtil.getMasterFX(fxPackets);
        if (fx == null) {
            continue;
        }
        final long delta;
        if (lastUpdate == null) {
            delta = 1000;
        } else {
            delta = packetGroup.getDateMillis() - lastUpdate;
        }
        lastUpdate = packetGroup.getDateMillis();
        stateHandler.update(delta, fx, temperature);
        FXChargingPacket fxChargingPacket = new ImmutableFXChargingPacket(fx.getIdentifier(), stateHandler.getMode(), stateHandler.getRemainingAbsorbTimeMillis(), stateHandler.getRemainingFloatTimeMillis(), stateHandler.getRemainingEqualizeTimeMillis(), settings.getAbsorbTimeMillis(), settings.getFloatTimeMillis(), settings.getEqualizeTimeMillis());
        r.add(new DataNode<>(fxChargingPacket, fx, packetGroup.getDateMillis(), packetGroup.getSourceId(fx), fragmentId));
    }
    if (r.isEmpty() && !sortedPackets.isEmpty()) {
        throw new UnexpectedResponseException("There must have been no FX packets or no rover packets!");
    }
    return r;
}
Also used : ArrayList(java.util.ArrayList) ImmutableFXChargingPacket(me.retrodaredevil.solarthing.solar.outback.fx.charge.ImmutableFXChargingPacket) FXChargingPacket(me.retrodaredevil.solarthing.solar.outback.fx.charge.FXChargingPacket) FXStatusPacket(me.retrodaredevil.solarthing.solar.outback.fx.FXStatusPacket) FXChargingSettings(me.retrodaredevil.solarthing.solar.outback.fx.charge.FXChargingSettings) DataNode(me.retrodaredevil.solarthing.rest.graphql.packets.nodes.DataNode) ArrayList(java.util.ArrayList) List(java.util.List) FragmentedPacketGroup(me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup) Packet(me.retrodaredevil.solarthing.packets.Packet) FXStatusPacket(me.retrodaredevil.solarthing.solar.outback.fx.FXStatusPacket) FXChargingTemperatureAdjustPacket(me.retrodaredevil.solarthing.solar.outback.fx.meta.FXChargingTemperatureAdjustPacket) ImmutableFXChargingPacket(me.retrodaredevil.solarthing.solar.outback.fx.charge.ImmutableFXChargingPacket) TargetedMetaPacket(me.retrodaredevil.solarthing.type.closed.meta.TargetedMetaPacket) FXChargingPacket(me.retrodaredevil.solarthing.solar.outback.fx.charge.FXChargingPacket) FXChargingSettingsPacket(me.retrodaredevil.solarthing.solar.outback.fx.meta.FXChargingSettingsPacket) MetaDatabase(me.retrodaredevil.solarthing.type.closed.meta.MetaDatabase) BatteryTemperature(me.retrodaredevil.solarthing.solar.common.BatteryTemperature) ImmutableFXChargingPacket(me.retrodaredevil.solarthing.solar.outback.fx.charge.ImmutableFXChargingPacket) TargetedMetaPacket(me.retrodaredevil.solarthing.type.closed.meta.TargetedMetaPacket) FXChargingTemperatureAdjustPacket(me.retrodaredevil.solarthing.solar.outback.fx.meta.FXChargingTemperatureAdjustPacket) UnexpectedResponseException(me.retrodaredevil.solarthing.rest.exceptions.UnexpectedResponseException) FXChargingSettingsPacket(me.retrodaredevil.solarthing.solar.outback.fx.meta.FXChargingSettingsPacket) FXChargingStateHandler(me.retrodaredevil.solarthing.solar.outback.fx.charge.FXChargingStateHandler) GraphQLQuery(io.leangen.graphql.annotations.GraphQLQuery)

Example 3 with FragmentedPacketGroup

use of me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup in project solarthing by wildmountainfarms.

the class DefaultIdentificationCacheCreator method convertPackets.

@SuppressWarnings("unchecked")
private static <T extends Identifiable> Map<String, Map<IdentifierFragment, List<TimestampedPacket<T>>>> convertPackets(List<? extends FragmentedPacketGroup> packetGroups, Class<T> acceptedType) {
    Map<String, Map<IdentifierFragment, List<TimestampedPacket<T>>>> r = new HashMap<>();
    for (FragmentedPacketGroup packetGroup : packetGroups) {
        for (Packet packet : packetGroup.getPackets()) {
            if (!acceptedType.isInstance(packet)) {
                continue;
            }
            T identifiablePacket = (T) packet;
            String sourceId = packetGroup.getSourceId(packet);
            int fragmentId = packetGroup.getFragmentId(packet);
            Identifier identifier = identifiablePacket.getIdentifier();
            IdentifierFragment identifierFragment = IdentifierFragment.create(fragmentId, identifier);
            List<TimestampedPacket<T>> list = r.computeIfAbsent(sourceId, k -> new HashMap<>()).computeIfAbsent(identifierFragment, k -> new ArrayList<>());
            long dateMillis = packetGroup.getDateMillisOrKnown(packet);
            list.add(new TimestampedPacket<>(identifiablePacket, dateMillis));
        }
    }
    return r;
}
Also used : FragmentedPacketGroup(me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup) Packet(me.retrodaredevil.solarthing.packets.Packet) Identifiable(me.retrodaredevil.solarthing.packets.identification.Identifiable) java.util(java.util) DefaultIdentificationCacheDataPacket(me.retrodaredevil.solarthing.type.cache.packets.DefaultIdentificationCacheDataPacket) IdentificationCacheNode(me.retrodaredevil.solarthing.type.cache.packets.IdentificationCacheNode) FragmentedPacketGroup(me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup) IdentificationCacheDataPacket(me.retrodaredevil.solarthing.type.cache.packets.IdentificationCacheDataPacket) Instant(java.time.Instant) InstancePacketGroup(me.retrodaredevil.solarthing.packets.collection.InstancePacketGroup) Identifier(me.retrodaredevil.solarthing.packets.identification.Identifier) IdentificationCacheData(me.retrodaredevil.solarthing.type.cache.packets.data.IdentificationCacheData) Duration(java.time.Duration) Objects.requireNonNull(java.util.Objects.requireNonNull) TimestampedPacket(me.retrodaredevil.solarthing.packets.TimestampedPacket) IdentifierFragment(me.retrodaredevil.solarthing.packets.identification.IdentifierFragment) Packet(me.retrodaredevil.solarthing.packets.Packet) DefaultIdentificationCacheDataPacket(me.retrodaredevil.solarthing.type.cache.packets.DefaultIdentificationCacheDataPacket) IdentificationCacheDataPacket(me.retrodaredevil.solarthing.type.cache.packets.IdentificationCacheDataPacket) TimestampedPacket(me.retrodaredevil.solarthing.packets.TimestampedPacket) Identifier(me.retrodaredevil.solarthing.packets.identification.Identifier) IdentifierFragment(me.retrodaredevil.solarthing.packets.identification.IdentifierFragment) TimestampedPacket(me.retrodaredevil.solarthing.packets.TimestampedPacket)

Example 4 with FragmentedPacketGroup

use of me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup in project solarthing by wildmountainfarms.

the class PacketUtil method convertPackets.

/**
 * @return A mutable list of packets of a certain type
 */
@SuppressWarnings("unchecked")
public static <T> List<PacketNode<T>> convertPackets(List<? extends FragmentedPacketGroup> packetGroups, Class<T> acceptClass, PacketFilter filter) {
    List<PacketNode<T>> r = new ArrayList<>();
    for (FragmentedPacketGroup packetGroup : packetGroups) {
        for (Packet packet : packetGroup.getPackets()) {
            if (!acceptClass.isInstance(packet)) {
                continue;
            }
            int fragmentId = packetGroup.getFragmentId(packet);
            String sourceId = packetGroup.getSourceId(packet);
            long dateMillis = packetGroup.getDateMillisOrKnown(packet);
            PacketNode<T> packetNode = new PacketNode<>((T) packet, dateMillis, sourceId, fragmentId);
            if (filter.keep(packetNode)) {
                r.add(packetNode);
            }
        }
    }
    return r;
}
Also used : FragmentedPacketGroup(me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup) Packet(me.retrodaredevil.solarthing.packets.Packet) ArrayList(java.util.ArrayList) PacketNode(me.retrodaredevil.solarthing.rest.graphql.packets.nodes.PacketNode)

Example 5 with FragmentedPacketGroup

use of me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup in project solarthing by wildmountainfarms.

the class PVOutputHandler method getStatus.

public AddStatusParameters getStatus(long dayStartTimeMillis, List<FragmentedPacketGroup> packetGroupList) {
    FragmentedPacketGroup latestPacketGroup = packetGroupList.get(packetGroupList.size() - 1);
    LOGGER.debug("Continuing with the latest packet group. Day start: " + dayStartTimeMillis);
    AddStatusParametersBuilder addStatusParametersBuilder = createStatusBuilder(zoneId, latestPacketGroup.getDateMillis());
    setStatusPowerValues(addStatusParametersBuilder, latestPacketGroup);
    setStatusEnergyValues(addStatusParametersBuilder, packetGroupList, AccumulationConfig.createDefault(dayStartTimeMillis));
    for (Packet packet : latestPacketGroup.getPackets()) {
        if (packet instanceof PVCurrentAndVoltage) {
            int fragmentId = latestPacketGroup.getFragmentId(packet);
            PVCurrentAndVoltage pvCurrentAndVoltage = (PVCurrentAndVoltage) packet;
            IdentifierFragment identifierFragment = IdentifierFragment.create(fragmentId, pvCurrentAndVoltage.getIdentifier());
            if (voltageIdentifierFragmentMatcher.matches(identifierFragment)) {
                float voltage = pvCurrentAndVoltage.getPVVoltage().floatValue();
                addStatusParametersBuilder.setVoltage(voltage);
            }
        } else if (packet instanceof TemperaturePacket) {
            int fragmentId = latestPacketGroup.getFragmentId(packet);
            TemperaturePacket temperaturePacket = (TemperaturePacket) packet;
            IdentifierFragment identifierFragment = IdentifierFragment.create(fragmentId, temperaturePacket.getIdentifier());
            if (temperatureIdentifierFragmentMatcher.matches(identifierFragment)) {
                float temperatureCelsius = temperaturePacket.getTemperatureCelsius();
                if (!TemperaturePacket.POSSIBLE_BAD_VALUES.contains(temperatureCelsius)) {
                    addStatusParametersBuilder.setTemperatureCelsius(temperatureCelsius);
                } else {
                    LOGGER.info("Not setting temperature: " + temperatureCelsius + " because it could be a bad reading");
                }
            }
        }
    }
    return addStatusParametersBuilder.build();
}
Also used : FragmentedPacketGroup(me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup) Packet(me.retrodaredevil.solarthing.packets.Packet) DailyFXPacket(me.retrodaredevil.solarthing.solar.outback.fx.extra.DailyFXPacket) TemperaturePacket(me.retrodaredevil.solarthing.misc.weather.TemperaturePacket) IdentifierFragment(me.retrodaredevil.solarthing.packets.identification.IdentifierFragment) PVCurrentAndVoltage(me.retrodaredevil.solarthing.solar.common.PVCurrentAndVoltage) AddStatusParametersBuilder(me.retrodaredevil.solarthing.pvoutput.data.AddStatusParametersBuilder) TemperaturePacket(me.retrodaredevil.solarthing.misc.weather.TemperaturePacket)

Aggregations

FragmentedPacketGroup (me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup)14 Packet (me.retrodaredevil.solarthing.packets.Packet)7 ArrayList (java.util.ArrayList)6 LatestFragmentedPacketGroupEnvironment (me.retrodaredevil.solarthing.actions.environment.LatestFragmentedPacketGroupEnvironment)5 IOException (java.io.IOException)4 List (java.util.List)4 SolarThingDatabaseException (me.retrodaredevil.solarthing.database.exception.SolarThingDatabaseException)3 IdentifierFragment (me.retrodaredevil.solarthing.packets.identification.IdentifierFragment)3 FXStatusPacket (me.retrodaredevil.solarthing.solar.outback.fx.FXStatusPacket)3 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)2 Duration (java.time.Duration)2 SimpleAction (me.retrodaredevil.action.SimpleAction)2 ActionNode (me.retrodaredevil.action.node.ActionNode)2 ActionEnvironment (me.retrodaredevil.action.node.environment.ActionEnvironment)2 InjectEnvironment (me.retrodaredevil.action.node.environment.InjectEnvironment)2 NanoTimeProviderEnvironment (me.retrodaredevil.action.node.environment.NanoTimeProviderEnvironment)2 VariableEnvironment (me.retrodaredevil.action.node.environment.VariableEnvironment)2 FragmentedPacketGroupProvider (me.retrodaredevil.solarthing.FragmentedPacketGroupProvider)2 MillisQueryBuilder (me.retrodaredevil.solarthing.database.MillisQueryBuilder)2 TimestampedPacket (me.retrodaredevil.solarthing.packets.TimestampedPacket)2