- Platform information:
- Hardware: Raspberry Pi 4 Model B Rev 1.1 ; 4GB memory
- Host: Linux openhabian 5.15.76-v7l+ #1597 SMP Fri Nov 4 12:14:58 GMT 2022 armv7l GNU/Linux
- Distro: Raspbian GNU/Linux 11 (bullseye)
- openjdk version “11.0.18” 2023-01-17
- OpenJDK Runtime Environment (build 11.0.18+10-post-Raspbian-1deb11u1)
- OpenJDK Server VM (build 11.0.18+10-post-Raspbian-1deb11u1, mixed mode)
- OH Version: 3.4.3 (Build)
- Installation method: openhabian
I have a rule, which, in essence, should output a duration formatted as HH:mm.
The rule takes the battery SoC, calculates how much capacity is missing; takes the current battery input power and calculates the time when the battery reaches a SoC of 100%.
Here it is:
rule "SP-PRO: calculate when battery charging is complete"
when
Item spm_Battery_SoC changed
/*
or
// s m h D M DoW Y
Time cron "1 0/1 * * * ?"
// here: every 10 minutes; use http://www.cronmaker.com/
*/
then
//val RULE_ID = 05
if ((tod_TimeOfDay.state == "DAY") && (spp_SOC100RanOnce.state == OFF))
{
// in Wh: 3.2V * 16 cells * 400 Ah
val BATTERY_CAPACITY = 20480
val MISSING_CAPACITY = (BATTERY_CAPACITY - (BATTERY_CAPACITY * (spm_Battery_SoC.state as Number) / 100)).intValue
val HOURS_TO_CHARGE = MISSING_CAPACITY / spm_Battery_Power.state as Number
// split decimal hours to hours and MINUTES
val HOURS = (Math::floor(HOURS_TO_CHARGE.floatValue)).intValue
val MINUTES = Math::round((HOURS_TO_CHARGE.floatValue - HOURS) * 60)
// date time as string
// 2024-03-27T01:30:01.740017+10:00[Australia/Brisbane]
val CHARGED_AT_TIME = now().plusHours(HOURS).plusMinutes(MINUTES)
// brute force formatting of 2024-03-25T13:02:34.021835+10:00[Australia/Brisbane]
// change the time format to string; split the string at "T" and
// get the second element: 13:02:34.021835+10:00[Australia/Brisbane]
val CHARGED_AT_TIME_PART = CHARGED_AT_TIME.toString().split("T").get(1)
// split second element at the dot nd get the first element: 13:02:34
val TIME_STAMP_PART = CHARGED_AT_TIME_PART.split("\\.").get(0)
// take the first element and split at the colon
val TIME_STAMP_SPLIT = TIME_STAMP_PART.split(":")
val HOUR = TIME_STAMP_SPLIT.get(0)
val MINUTE = TIME_STAMP_SPLIT.get(1)
//logInfo(LOG_PREFIX + RULE_ID + ".01", "Battery charged at {}:{}", HOUR, MINUTE)
postUpdate(SPPRO_Battery_Charged_ETA, HOUR + ":" + MINUTE)
}
end
I have used brute force to convert DateTime to HH:mm. The problem is, when the ETA to SoC of 100% is falling onto the next day. E.g., it may show 02:45.
There must be a more elegant approach.
So I tried this:
rule "SP-PRO: calculate when battery charging is complete"
when
Item spm_Battery_SoC changed
or
// s m h D M DoW Y
Time cron "1 0/1 * * * ?"
// here: every 10 minutes; use http://www.cronmaker.com/
then
val RULE_ID = 05
if ((tod_TimeOfDay.state == "DAY") && (spp_SOC100RanOnce.state == OFF))
{
// in Wh: 3.2V * 16 cells * 400 Ah
val BATTERY_CAPACITY = 20480
val MISSING_CAPACITY = (BATTERY_CAPACITY - (BATTERY_CAPACITY * (spm_Battery_SoC.state as Number) / 100)).intValue
val HOURS_TO_CHARGE = MISSING_CAPACITY / spm_Battery_Power.state as Number
// split decimal hours to hours and MINUTES
val HOURS = (Math::floor(HOURS_TO_CHARGE.floatValue)).intValue
val MINUTES = Math::round((HOURS_TO_CHARGE.floatValue - HOURS) * 60)
// date time as string
// 2024-03-27T01:30:01.740017+10:00[Australia/Brisbane]
val CHARGED_AT_TIME = now().plusHours(HOURS).plusMinutes(MINUTES)
// change starts here!
// PT16H16M59.998243S
val CHARGED_IN = Duration.between(now(), CHARGED_AT_TIME)
val DURATION_HOURS = CHARGED_IN.toHours // e.g. 6.75
val DURATION_MINUTES = CHARGED_IN.toMinutesPart // e.g. 45
var DEBUG_FLAG = 1
if (DEBUG_FLAG == 1)
{
logInfo(LOG_PREFIX + RULE_ID + ".0c", "Battery charged at {}", CHARGED_AT_TIME)
logInfo(LOG_PREFIX + RULE_ID + ".0d", "Battery charged in {}", CHARGED_IN)
logInfo(LOG_PREFIX + RULE_ID + ".0e", "DURATION_HOURS ... {}", DURATION_HOURS)
logInfo(LOG_PREFIX + RULE_ID + ".0f", "DURATION_MINUTES . {}", DURATION_MINUTES)
}
val DURATION_STRING = CHARGED_IN.format(DateTimeFormatter.ofPattern("HH:mm"))
logInfo(LOG_PREFIX + RULE_ID + ".0g", "DURATION_STRING .. {}", DURATION_STRING)
postUpdate(SPPRO_Battery_Charged_ETA, DURATION_STRING)
}
end
However, I get stuck with The method or field DateTimeFormatter is undefined
… in the line:
var duration_string = charged_in.format(DateTimeFormatter.ofPattern("HH:mm"))
Any hints appreciated.