use of me.retrodaredevil.solarthing.packets.Packet in project solarthing by wildmountainfarms.
the class OnMateCommandSent method onCommandExecute.
@Override
public void onCommandExecute(SourcedCommand<MateCommand> command) {
OpenSource source = command.getSource();
ExecutionReason reason = new OpenSourceExecutionReason(source);
Packet packet = new ImmutableSuccessMateCommandPacket(SuccessMateCommandPacket.VERSION_LATEST, command.getCommand(), // for legacy reasons, include the data source converted to a string
source.toDataSource().toString(), reason);
packetListReceiver.receive(Collections.singletonList(packet));
}
use of me.retrodaredevil.solarthing.packets.Packet in project solarthing by wildmountainfarms.
the class PacketListReceiverHandler method uploadSimple.
/**
* This method is used to be able to upload packets in a simple way without dealing with {@link PacketListReceiver}s.
* <p>
* If {@code packets} is empty, this method does nothing. If not empty, it may add additional packets, turn into a {@link PacketCollection},
* then "handles" the {@link PacketCollection}, which usually means to persist the {@link PacketCollection} in a database.
* @param packets The packets to upload
*/
public void uploadSimple(Instant now, List<? extends Packet> packets) {
List<Packet> mutablePackets = new ArrayList<>(packets);
if (mutablePackets.isEmpty()) {
return;
}
// this call may mutate mutablePackets, which is why we need it in the first place
packetListReceiver.receive(mutablePackets);
PacketCollection packetCollection = PacketCollections.createFromPackets(now, mutablePackets, idGenerator, zoneId);
handleSinglePacketCollection(packetCollection);
}
use of me.retrodaredevil.solarthing.packets.Packet in project solarthing by wildmountainfarms.
the class InfluxDbPacketSaver method handle.
@Override
public void handle(PacketCollection packetCollection) throws PacketHandleException {
try (InfluxDB db = createDatabase()) {
final InstancePacketGroup packetGroup = PacketGroups.parseToInstancePacketGroup(packetCollection, DefaultInstanceOptions.REQUIRE_NO_DEFAULTS);
DefaultInstanceOptions.requireNoDefaults(packetGroup);
final String database = databaseNameGetter.getName(packetGroup);
try {
QueryResult result = db.query(new Query("CREATE DATABASE " + database, null, true));
String error = getError(result);
if (error != null) {
throw new PacketHandleException("Result got error! error: " + result);
}
} catch (InfluxDBException ex) {
throw new PacketHandleException("Unable to query the database!", ex);
}
final RetentionPolicySetting retentionPolicySetting = retentionPolicyGetter.getRetentionPolicySetting();
final String retentionPolicyName;
// region Retention Policy Creation Logic
if (retentionPolicySetting != null) {
retentionPolicyName = retentionPolicySetting.getName();
if (retentionPolicyName != null) {
final RetentionPolicy policy = retentionPolicySetting.getRetentionPolicy();
if (policy != null) {
final String policyString = policy.toPolicyStringInfluxDb1(retentionPolicyName, database);
final boolean needsAlter;
if (retentionPolicySetting.isTryToCreate()) {
final QueryResult result;
final String query = "CREATE " + policyString;
try {
result = db.query(new Query(query, null, true));
} catch (InfluxDBException ex) {
throw new PacketHandleException("Unable to query database to create retention policy: " + retentionPolicyName + " query: " + query, ex);
}
String error = getError(result);
if (retentionPolicySetting.isIgnoreUnsuccessfulCreate()) {
if (error != null) {
LOGGER.debug("We're going to ignore this error we got while trying to create a retention policy. Error: {}", error);
}
needsAlter = false;
} else {
if (error != null) {
LOGGER.debug("Got error while trying to create! Error: " + error);
}
needsAlter = error != null;
}
if (needsAlter && !retentionPolicySetting.isAutomaticallyAlter()) {
throw new PacketHandleException("Got error while trying to create retention policy: " + retentionPolicyName + ". Error: " + error);
}
} else {
needsAlter = true;
}
if (needsAlter) {
if (retentionPolicySetting.isAutomaticallyAlter()) {
final QueryResult alterResult;
try {
alterResult = db.query(new Query("ALTER " + policyString));
LOGGER.info(SolarThingConstants.SUMMARY_MARKER, "Successfully altered {} retention policy!", retentionPolicyName);
} catch (InfluxDBException ex) {
throw new PacketHandleException("Unable to query database to alter retention policy: " + retentionPolicyName, ex);
}
String error = getError(alterResult);
if (error != null) {
throw new PacketHandleException("Unable to alter retention policy: " + retentionPolicyName + ". Error: " + error);
}
} else {
throw new PacketHandleException("Retention policy: " + retentionPolicyName + " needs to be altered but automatically alter is false!");
}
}
}
}
} else {
retentionPolicyName = null;
}
// endregion
final long time = packetCollection.getDateMillis();
final BatchPoints points = BatchPoints.database(database).tag("sourceId", packetGroup.getSourceId()).tag("fragmentId", "" + packetGroup.getFragmentId()).consistency(InfluxDB.ConsistencyLevel.ALL).retentionPolicy(// may be null, but that's OK
retentionPolicyName).build();
int packetsWritten = 0;
for (Packet packet : packetGroup.getPackets()) {
Point.Builder pointBuilder = pointCreator.createBuilder(packet).time(time, TimeUnit.MILLISECONDS);
Collection<String> tagKeys = PointUtil.getTagKeys(packet.getClass());
ObjectNode json = OBJECT_MAPPER.valueToTree(packet);
for (Map.Entry<String, ValueNode> entry : PointUtil.flattenJsonObject(json)) {
String key = entry.getKey();
ValueNode prim = entry.getValue();
if (tagKeys.contains(key)) {
pointBuilder.tag(key, prim.asText());
}
if (prim.isNumber()) {
// always store as float datatype
pointBuilder.addField(key, prim.asDouble());
} else if (prim.isTextual() || prim.isBinary()) {
pointBuilder.addField(key, prim.asText());
} else if (prim.isBoolean()) {
pointBuilder.addField(key, prim.asBoolean());
} else
throw new AssertionError("This primitive isn't a number, string/binary or boolean! It's: " + prim + " class: " + prim.getClass() + " text=" + prim.asText());
}
points.point(pointBuilder.build());
packetsWritten++;
}
try {
db.write(points);
} catch (InfluxDBException ex) {
throw new PacketHandleException("We were able to query the database, but unable to write the points to it!", ex);
}
LOGGER.debug("Wrote {} packets to InfluxDB! database={} retention policy={}", packetsWritten, database, retentionPolicyName);
}
}
use of me.retrodaredevil.solarthing.packets.Packet in project solarthing by wildmountainfarms.
the class StatusChatBotHandler method handleMessage.
@Override
public boolean handleMessage(Message message, MessageSender messageSender) {
if (ChatBotUtil.isSimilar("battery voltage", message.getText())) {
FragmentedPacketGroup packetGroup = packetGroupProvider.getPacketGroup();
Float batteryVoltageAverage = BatteryUtil.getBatteryVoltageAverage(packetGroup);
if (batteryVoltageAverage == null) {
messageSender.sendMessage("Battery voltage unavailable from latest data. Sorry!");
} else {
messageSender.sendMessage("Battery voltage: " + Formatting.HUNDREDTHS_FORMAT.format(batteryVoltageAverage));
}
return true;
} else if (ChatBotUtil.isSimilar("battery temperature", message.getText()) || ChatBotUtil.isSimilar("battery temp", message.getText())) {
FragmentedPacketGroup packetGroup = packetGroupProvider.getPacketGroup();
List<String> lines = new ArrayList<>();
for (Packet packet : packetGroup.getPackets()) {
int fragmentId = packetGroup.getFragmentId(packet);
if (packet instanceof BatteryTemperature && packet instanceof Identifiable) {
float temperature = ((BatteryTemperature) packet).getBatteryTemperatureFahrenheit();
IdentityInfo identityInfo = ((Identifiable) packet).getIdentityInfo();
lines.add(identityInfo.getDisplayName() + " (" + fragmentId + "): " + temperature + "F");
}
}
if (lines.isEmpty()) {
messageSender.sendMessage("No devices to read temperature!");
} else {
messageSender.sendMessage(String.join("\n", lines));
}
return true;
} else if (ChatBotUtil.isSimilar("alter", message.getText())) {
List<VersionedPacket<StoredAlterPacket>> alterPackets = alterPacketsProvider.getPackets();
if (alterPackets == null) {
messageSender.sendMessage("Error - Must have failed to query alter database");
} else {
List<String> scheduledCommandLines = new ArrayList<>();
for (VersionedPacket<StoredAlterPacket> versionedPacket : alterPackets) {
StoredAlterPacket storedAlterPacket = versionedPacket.getPacket();
AlterPacket alterPacket = storedAlterPacket.getPacket();
if (alterPacket instanceof ScheduledCommandPacket) {
ScheduledCommandData data = ((ScheduledCommandPacket) alterPacket).getData();
// ExecutionReason executionReason = ((ScheduledCommandPacket) alterPacket).getExecutionReason();
String timeString = TimeUtil.instantToSlackDateSeconds(Instant.ofEpochMilli(data.getScheduledTimeMillis()));
scheduledCommandLines.add(data.getCommandName() + " - " + timeString);
}
}
if (scheduledCommandLines.isEmpty()) {
messageSender.sendMessage("No scheduled commands (from " + alterPackets.size() + " alter packets)");
} else {
messageSender.sendMessage("Scheduled commands:\n\t" + String.join("\n\t", scheduledCommandLines));
}
}
return true;
}
return false;
}
use of me.retrodaredevil.solarthing.packets.Packet in project solarthing by wildmountainfarms.
the class InfluxDb2PacketSaver method handle.
@Override
public void handle(PacketCollection packetCollection) throws PacketHandleException {
final InstancePacketGroup packetGroup = PacketGroups.parseToInstancePacketGroup(packetCollection, DefaultInstanceOptions.REQUIRE_NO_DEFAULTS);
DefaultInstanceOptions.requireNoDefaults(packetGroup);
Organization organization = findOrCreateOrg();
Bucket bucket = findOrCreateBucket(bucketNameGetter.getName(packetGroup), organization);
final long time = packetCollection.getDateMillis();
List<Point> points = new ArrayList<>();
for (Packet packet : packetGroup.getPackets()) {
Point point = pointCreator.createBuilder(packet).time(time, WritePrecision.MS);
Collection<String> tagKeys = PointUtil.getTagKeys(packet.getClass());
ObjectNode json = OBJECT_MAPPER.valueToTree(packet);
for (Map.Entry<String, ValueNode> entry : PointUtil.flattenJsonObject(json)) {
String key = entry.getKey();
ValueNode prim = entry.getValue();
if (tagKeys.contains(key)) {
point.addTag(key, prim.asText());
}
if (prim.isNumber()) {
// always store as float datatype because you can never change the type from int to float easily
final Number value;
if (prim.isBigDecimal()) {
DecimalNode decimal = (DecimalNode) prim;
value = decimal.decimalValue();
} else {
value = prim.asDouble();
}
point.addField(key, value);
} else if (prim.isTextual() || prim.isBinary()) {
point.addField(key, prim.asText());
} else if (prim.isBoolean()) {
point.addField(key, prim.asBoolean());
} else
throw new AssertionError("This primitive isn't a number, string/binary or boolean! It's: " + prim + " class: " + prim.getClass() + " text=" + prim.asText());
}
points.add(point);
}
try {
client.getWriteApiBlocking().writePoints(bucket.getName(), bucket.getOrgID(), points);
} catch (InfluxException exception) {
throw new PacketHandleException("Could not write points", exception);
}
}
Aggregations