diff --git a/conf/alarms.conf b/conf/alarms.conf index f1ad8f0..2141ccd 100644 --- a/conf/alarms.conf +++ b/conf/alarms.conf @@ -1,4 +1,4 @@ # Asset Direction Target TRIGGER SEVERITY NOTE ############################################################# -SOL BELOW 70.0 ONETIME 2 "ALARM: Risiko for Perps Solana long LIKVIDERING!" -SOL BELOW 71.4 ONETIME 2 "ALARM: Risiko for Solana Raydium LÅN LIKVIDERING!" +SOL BELOW 170.0 ONETIME INFO "EMERGENCY: Risiko for Perps Solana long LIKVIDERING!" +#SOL BELOW 71.4 ONETIME CRITICAL "CRITICAL: Risiko for Solana Raydium LÅN LIKVIDERING!" diff --git a/src/main/tjava/com/r35157/jupiterperpsalarm/AlarmSeverity.tjava b/src/main/tjava/com/r35157/jupiterperpsalarm/AlarmSeverity.tjava new file mode 100644 index 0000000..5f6f719 --- /dev/null +++ b/src/main/tjava/com/r35157/jupiterperpsalarm/AlarmSeverity.tjava @@ -0,0 +1,10 @@ +package com.r35157.jupiterperpsalarm; + +public enum AlarmSeverity { + EMERGENCY, // Repeated wake-up alarm - sound always + CRITICAL, // One-shot wake-up alarm - sound always + WARN, // Audible warning - respecting quiet hours though + INFO, // Normal notification with visual and audible feedback + SILENT, // Low-priority notification - visual feedback without sound/vibration + GHOST // No visual/audible notification - only visible inside the Pushover app +} diff --git a/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/AlarmConfigurationParser.tjava b/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/AlarmConfigurationParser.tjava index 5857cbf..8ded15f 100644 --- a/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/AlarmConfigurationParser.tjava +++ b/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/AlarmConfigurationParser.tjava @@ -1,5 +1,7 @@ package com.r35157.jupiterperpsalarm.impl.ref; +import com.r35157.jupiterperpsalarm.AlarmSeverity; + import java.io.IOException; import java.math.BigDecimal; import java.nio.file.Files; @@ -44,15 +46,21 @@ public final class AlarmConfigurationParser { JupiterPerpsAsset asset = JupiterPerpsAsset.valueOf( cursor.nextToken("asset").toUpperCase(Locale.ROOT) ); + PriceDirection direction = PriceDirection.valueOf( cursor.nextToken("direction").toUpperCase(Locale.ROOT) ); BigDecimal target = new BigDecimal(cursor.nextToken("target")); + AlarmTrigger trigger = AlarmTrigger.valueOf( cursor.nextToken("trigger").toUpperCase(Locale.ROOT) ); - int severity = Integer.parseInt(cursor.nextToken("severity")); + + AlarmSeverity severity = AlarmSeverity.valueOf( + cursor.nextToken("severity").toUpperCase() + ); + String note = cursor.nextQuotedString("note"); cursor.skipWhitespace(); diff --git a/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/JupiterPerpsAlarmImpl.tjava b/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/JupiterPerpsAlarmImpl.tjava index 2ecf5e7..6b0710d 100644 --- a/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/JupiterPerpsAlarmImpl.tjava +++ b/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/JupiterPerpsAlarmImpl.tjava @@ -89,7 +89,7 @@ public final class JupiterPerpsAlarmImpl { asset.oracleAccount() ); assetDefinitions.forEach(definition -> System.out.printf( - " %s %s USD, %s, severity=%d%n", + " %s %s USD, %s, severity=%s%n", definition.direction(), definition.target().toPlainString(), definition.trigger(), diff --git a/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/PriceAlarmDefinition.tjava b/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/PriceAlarmDefinition.tjava index d89ce33..a4d4d5e 100644 --- a/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/PriceAlarmDefinition.tjava +++ b/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/PriceAlarmDefinition.tjava @@ -1,5 +1,7 @@ package com.r35157.jupiterperpsalarm.impl.ref; +import com.r35157.jupiterperpsalarm.AlarmSeverity; + import java.math.BigDecimal; import java.util.Objects; @@ -8,7 +10,7 @@ public record PriceAlarmDefinition( PriceDirection direction, BigDecimal target, AlarmTrigger trigger, - int severity, + AlarmSeverity severity, String note ) { public PriceAlarmDefinition { @@ -21,8 +23,5 @@ public record PriceAlarmDefinition( if (target.signum() <= 0) { throw new IllegalArgumentException("Target price must be positive"); } - if (severity < 0) { - throw new IllegalArgumentException("Severity must be zero or positive"); - } } } diff --git a/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/PushoverAlarmAction.tjava b/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/PushoverAlarmAction.tjava index 2b5bd0d..ac746f7 100644 --- a/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/PushoverAlarmAction.tjava +++ b/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/PushoverAlarmAction.tjava @@ -1,5 +1,7 @@ package com.r35157.jupiterperpsalarm.impl.ref; +import com.r35157.jupiterperpsalarm.AlarmSeverity; + import java.net.URI; import java.net.URLEncoder; import java.net.http.HttpClient; @@ -28,13 +30,13 @@ public final class PushoverAlarmAction implements AlarmAction { price.slot() ); - // Severity and note are intentionally parsed and retained in the model, - // but are not used by Pushover yet. + // TODO: Note is intentionally parsed and retained in the model, but are not used by Pushover yet. + // https://git.r35157.com/r35157/com_r35157_nenjim-hubd-impl_ref/issues/7 String body = form("token", applicationToken) + "&" + form("user", userKey) + "&" + form("title", title) + "&" + form("message", message) + "&" + - "priority=2&retry=30&expire=10800&sound=persistent"; + createPushoverSeverityParameters(alarm.severity());; HttpRequest request = HttpRequest.newBuilder(PUSHOVER_URI) .timeout(Duration.ofSeconds(15)) @@ -56,7 +58,7 @@ public final class PushoverAlarmAction implements AlarmAction { response.body() ); } else { - System.out.println("Pushover emergency alarm sent."); + System.out.println("Pushover alarm sent: " + alarm.severity()); } }); } @@ -66,6 +68,17 @@ public final class PushoverAlarmAction implements AlarmAction { URLEncoder.encode(value, StandardCharsets.UTF_8); } + private static String createPushoverSeverityParameters(AlarmSeverity severity) { + return switch (severity) { + case EMERGENCY -> "priority=2&retry=30&expire=10800&sound=persistent"; + case CRITICAL -> "priority=1&sound=spacealarm"; + case WARN -> "priority=0&sound=siren"; + case INFO -> "priority=0"; + case SILENT -> "priority=-1"; + case GHOST -> "priority=-2"; + }; + } + private final HttpClient httpClient = HttpClient.newHttpClient(); private final String applicationToken; private final String userKey; diff --git a/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/SelfTest.tjava b/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/SelfTest.tjava index 03ba83a..e216116 100644 --- a/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/SelfTest.tjava +++ b/src/main/tjava/com/r35157/jupiterperpsalarm/impl/ref/SelfTest.tjava @@ -1,5 +1,7 @@ package com.r35157.jupiterperpsalarm.impl.ref; +import com.r35157.jupiterperpsalarm.AlarmSeverity; + import java.math.BigDecimal; import java.time.Instant; import java.util.ArrayList; @@ -17,14 +19,14 @@ public final class SelfTest { private static void configurationParserTest() { PriceAlarmDefinition alarm = AlarmConfigurationParser.parseLine( - "SOL ABOVE 75.7 ONETIME 2 \"ALARM: Risiko for likvidering!\"" + "SOL ABOVE 75.7 ONETIME CRITICAL \"ALARM: Risiko for likvidering!\"" ); require(alarm.asset() == JupiterPerpsAsset.SOL, "Asset parsing failed"); require(alarm.direction() == PriceDirection.ABOVE, "Direction parsing failed"); require(alarm.target().compareTo(new BigDecimal("75.7")) == 0, "Target parsing failed"); require(alarm.trigger() == AlarmTrigger.ONETIME, "Trigger parsing failed"); - require(alarm.severity() == 2, "Severity parsing failed"); + require(alarm.severity() == AlarmSeverity.CRITICAL, "Severity parsing failed"); require(alarm.note().equals("ALARM: Risiko for likvidering!"), "Note parsing failed"); } @@ -89,7 +91,7 @@ public final class SelfTest { direction, new BigDecimal(target), trigger, - 2, + AlarmSeverity.CRITICAL, "ignored for now" ); }