Search in sources :

Example 1 with Identifiable

use of me.retrodaredevil.solarthing.packets.identification.Identifiable 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 2 with Identifiable

use of me.retrodaredevil.solarthing.packets.identification.Identifiable in project solarthing by wildmountainfarms.

the class PacketFinder method updateWithRange.

private void updateWithRange(long queryStart, long queryEnd) {
    List<? extends InstancePacketGroup> rawPackets = simpleQueryHandler.queryStatus(queryStart, queryEnd, null);
    synchronized (cacheMap) {
        for (InstancePacketGroup instancePacketGroup : rawPackets) {
            int fragmentId = instancePacketGroup.getFragmentId();
            for (Packet packet : instancePacketGroup.getPackets()) {
                if (packet instanceof Identifiable) {
                    Identifiable identifiable = (Identifiable) packet;
                    IdentifierFragment packetIdentifierFragment = IdentifierFragment.create(fragmentId, identifiable.getIdentifier());
                    cacheMap.putIfAbsent(packetIdentifierFragment, identifiable);
                }
            }
        }
    }
}
Also used : InstancePacketGroup(me.retrodaredevil.solarthing.packets.collection.InstancePacketGroup) Packet(me.retrodaredevil.solarthing.packets.Packet) IdentifierFragment(me.retrodaredevil.solarthing.packets.identification.IdentifierFragment) Identifiable(me.retrodaredevil.solarthing.packets.identification.Identifiable)

Example 3 with Identifiable

use of me.retrodaredevil.solarthing.packets.identification.Identifiable in project solarthing by wildmountainfarms.

the class PacketFinder method findPacket.

@Nullable
public synchronized Identifiable findPacket(IdentifierFragment identifierFragment, long queryStart, long queryEnd) {
    Identifiable result = cacheMap.get(identifierFragment);
    if (result != null) {
        return result;
    }
    updateWithRange(queryStart, queryEnd);
    return cacheMap.get(identifierFragment);
}
Also used : Identifiable(me.retrodaredevil.solarthing.packets.identification.Identifiable) Nullable(me.retrodaredevil.solarthing.annotations.Nullable)

Example 4 with Identifiable

use of me.retrodaredevil.solarthing.packets.identification.Identifiable in project solarthing by wildmountainfarms.

the class RequireFullOutputActionNode method isFullOutput.

private boolean isFullOutput(FragmentedPacketGroup latestPacketGroup) {
    for (Map.Entry<Integer, List<String>> entry : requiredIdentifierMap.entrySet()) {
        int desiredFragmentId = entry.getKey();
        if (!latestPacketGroup.hasFragmentId(desiredFragmentId)) {
            continue;
        }
        for (String desiredIdentifierRepresentation : entry.getValue()) {
            for (Packet packet : latestPacketGroup.getPackets()) {
                int fragmentId = latestPacketGroup.getFragmentId(packet);
                if (fragmentId != desiredFragmentId) {
                    continue;
                }
                if (packet instanceof Identifiable) {
                    Identifier identifier = ((Identifiable) packet).getIdentifier();
                    if (desiredIdentifierRepresentation.equals(identifier.getRepresentation())) {
                        if (packet instanceof MXStatusPacket) {
                            MXStatusPacket mx = (MXStatusPacket) packet;
                            ChargerMode mode = mx.getChargingMode();
                            // Some old MX firmwares consistently report being in float mode after a full absorb cycle even after the daily reset.
                            // This configuration option allows us to treat float as full output for a given MX
                            boolean canIgnoreFloatMode = ignoreReportedMXFloatMap.getOrDefault(fragmentId, Collections.emptyList()).contains(desiredIdentifierRepresentation);
                            if (mode != ChargerMode.SILENT && mode != ChargerMode.BULK && (!canIgnoreFloatMode || mode != ChargerMode.FLOAT)) {
                                if (log) {
                                    LOGGER.info(identifier.getRepresentation() + " on fragment " + fragmentId + " is in mode " + mode.getModeName());
                                }
                                return false;
                            }
                        } else if (packet instanceof RoverStatusPacket) {
                            RoverStatusPacket rover = (RoverStatusPacket) packet;
                            ChargingState state = rover.getChargingMode();
                            if (state != ChargingState.ACTIVATED && state != ChargingState.DEACTIVATED && state != ChargingState.MPPT) {
                                if (log) {
                                    LOGGER.info(identifier.getRepresentation() + " on fragment " + fragmentId + " is in mode " + state.getModeName());
                                }
                                return false;
                            }
                        } else if (packet instanceof TracerStatusPacket) {
                            TracerStatusPacket tracer = (TracerStatusPacket) packet;
                            ChargingStatus status = tracer.getChargingMode();
                            // we currently cannot tell if while in BOOST or EQUALIZE if the controller is actually in Bulk, so float is the only mode we know that isn't at full output
                            if (status == ChargingStatus.FLOAT) {
                                if (log) {
                                    LOGGER.info(identifier.getRepresentation() + " on fragment " + fragmentId + " is in mode " + status.getModeName());
                                }
                                return false;
                            }
                        }
                    }
                }
            }
        }
    }
    return true;
}
Also used : Packet(me.retrodaredevil.solarthing.packets.Packet) MXStatusPacket(me.retrodaredevil.solarthing.solar.outback.mx.MXStatusPacket) TracerStatusPacket(me.retrodaredevil.solarthing.solar.tracer.TracerStatusPacket) RoverStatusPacket(me.retrodaredevil.solarthing.solar.renogy.rover.RoverStatusPacket) ChargingStatus(me.retrodaredevil.solarthing.solar.tracer.mode.ChargingStatus) MXStatusPacket(me.retrodaredevil.solarthing.solar.outback.mx.MXStatusPacket) ChargerMode(me.retrodaredevil.solarthing.solar.outback.mx.ChargerMode) TracerStatusPacket(me.retrodaredevil.solarthing.solar.tracer.TracerStatusPacket) ChargingState(me.retrodaredevil.solarthing.solar.renogy.rover.ChargingState) Identifiable(me.retrodaredevil.solarthing.packets.identification.Identifiable) Identifier(me.retrodaredevil.solarthing.packets.identification.Identifier) RoverStatusPacket(me.retrodaredevil.solarthing.solar.renogy.rover.RoverStatusPacket) List(java.util.List) Map(java.util.Map)

Example 5 with Identifiable

use of me.retrodaredevil.solarthing.packets.identification.Identifiable in project solarthing by wildmountainfarms.

the class MqttPacketSaver method handle.

private void handle(InstancePacketGroup instancePacketGroup, PacketCollection entirePacketCollection) throws MqttException {
    DefaultInstanceOptions.requireNoDefaults(instancePacketGroup);
    long dateMillis = instancePacketGroup.getDateMillis();
    final String partiallyFormattedTopic = topicFormat.replace("%source", instancePacketGroup.getSourceId()).replace("%fragment", "" + instancePacketGroup.getFragmentId());
    client.connect(options);
    {
        // block for entire packet collection
        final String collectionJson;
        try {
            collectionJson = OBJECT_MAPPER.writeValueAsString(entirePacketCollection);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("We should be able to serial this to JSON!", e);
        }
        client.publish(partiallyFormattedTopic.replace("%identifier", "packetCollection"), collectionJson.getBytes(CHARSET), 2, retain);
    }
    client.publish(statusTopic, "online".getBytes(CHARSET), 1, retain);
    for (Packet packet : instancePacketGroup.getPackets()) {
        if (packet instanceof Identifiable) {
            Identifiable identifiable = (Identifiable) packet;
            String topic = partiallyFormattedTopic.replace("%identifier", identifiable.getIdentifier().getRepresentation()) + "/";
            final String rawJson;
            try {
                rawJson = OBJECT_MAPPER.writeValueAsString(packet);
            } catch (JsonProcessingException e) {
                throw new RuntimeException("We should be able to serialize this to JSON!", e);
            }
            client.publish(topic + "dateMillis", ("" + dateMillis).getBytes(CHARSET), 2, retain);
            client.publish(topic + "json", rawJson.getBytes(CHARSET), 2, retain);
            ObjectNode json = OBJECT_MAPPER.valueToTree(packet);
            for (Map.Entry<String, ValueNode> entry : PointUtil.flattenJsonObject(json, "/")) {
                String key = entry.getKey();
                ValueNode prim = entry.getValue();
                // Make individual fields use QoS of 1 because we want them all to go through, but no one should be using them as "event"-like packets
                client.publish(topic + "packet/" + key, prim.asText().getBytes(CHARSET), 1, retain);
            }
        }
    }
}
Also used : Packet(me.retrodaredevil.solarthing.packets.Packet) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) ValueNode(com.fasterxml.jackson.databind.node.ValueNode) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) Map(java.util.Map) Identifiable(me.retrodaredevil.solarthing.packets.identification.Identifiable)

Aggregations

Identifiable (me.retrodaredevil.solarthing.packets.identification.Identifiable)8 Packet (me.retrodaredevil.solarthing.packets.Packet)6 Identifier (me.retrodaredevil.solarthing.packets.identification.Identifier)3 IdentifierFragment (me.retrodaredevil.solarthing.packets.identification.IdentifierFragment)3 List (java.util.List)2 Map (java.util.Map)2 FragmentedPacketGroup (me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup)2 InstancePacketGroup (me.retrodaredevil.solarthing.packets.collection.InstancePacketGroup)2 ChargerMode (me.retrodaredevil.solarthing.solar.outback.mx.ChargerMode)2 MXStatusPacket (me.retrodaredevil.solarthing.solar.outback.mx.MXStatusPacket)2 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)1 ObjectNode (com.fasterxml.jackson.databind.node.ObjectNode)1 ValueNode (com.fasterxml.jackson.databind.node.ValueNode)1 Duration (java.time.Duration)1 Instant (java.time.Instant)1 java.util (java.util)1 ArrayList (java.util.ArrayList)1 Objects.requireNonNull (java.util.Objects.requireNonNull)1 Nullable (me.retrodaredevil.solarthing.annotations.Nullable)1 VersionedPacket (me.retrodaredevil.solarthing.database.VersionedPacket)1