|
| 1 | +#!/bin/sh |
| 2 | +# Convert SOC prediction + Magic SOC log lines to a unified markdown table. |
| 3 | +# Usage: ./soc_log_table.sh /tmp/hass.log |
| 4 | + |
| 5 | +FILE="${1:?usage: $0 <logfile>}" |
| 6 | + |
| 7 | +( |
| 8 | + # Charging prediction (deduplicated by timestamp+VIN) |
| 9 | + grep 'SOC: Predicted' "$FILE" | |
| 10 | + sed 's/.*\([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\)\.[0-9]*.* Predicted \([0-9.]*%\) for \([^ ]*\) (anchor=\([0-9.]*%\), +\([0-9.]* kWh\) net, eff=\([0-9]*%\)).*/\1|\3|Charging|\2 (anchor \4, +\5, \6)/' | |
| 11 | + sort -t'|' -k1,2 -u |
| 12 | + |
| 13 | + # Charging power + anchor + sync events |
| 14 | + grep -E 'Power update|SOC:.*Anchored session|SOC:.*Charging started|SOC:.*Charging stopped|SOC:.*sync' "$FILE" | |
| 15 | + sed \ |
| 16 | + -e 's/.*\([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\)\.[0-9]*.* Power update for \([^ ]*\): \(.*\)/\1|\2|Power|\3/' \ |
| 17 | + -e 's/.*\([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\)\.[0-9]*.* Anchored session for \([^ ]*\) at \(.*\)/\1|\2|Charge anchor|\3/' \ |
| 18 | + -e 's/.*\([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\)\.[0-9]*.* Charging started for \([^ ]*\)/\1|\2|Charge start|/' \ |
| 19 | + -e 's/.*\([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\)\.[0-9]*.* Charging stopped for \([^ ]*\)/\1|\2|Charge stop|/' \ |
| 20 | + -e 's/.*\([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\)\.[0-9]*.* BEV \([^ ]*\) .* BMW SOC \(.*\)/\1|\2|BMW sync|\3/' \ |
| 21 | + -e 's/.*\([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\)\.[0-9]*.* PHEV \([^ ]*\) .* BMW SOC \(.*\)/\1|\2|BMW sync|\3/' | |
| 22 | + grep '|' |
| 23 | + |
| 24 | + # Driving sessions (anchor, re-anchor, end, learning) |
| 25 | + grep 'Magic SOC:' "$FILE" | |
| 26 | + grep -E 'Anchor|Re-anchor|end_driving|learn|consumption' | |
| 27 | + grep -v 'Skipping anchor\|Set default\|reset button\|Created' | |
| 28 | + sed \ |
| 29 | + -e 's/.*\([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\)\.[0-9]*.* Anchored driving session for \([^ ]*\) at \([0-9.]*\)% \/ \([0-9.]*\) km (consumption=\([0-9.]*\) kWh\/km)/\1|\2|Drive anchor|\3% at \4 km (cons=\5)/' \ |
| 30 | + -e 's/.*\([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\)\.[0-9]*.* Re-anchored \([^ ]*\) from \([0-9.]*\)% to \([0-9.]*\)% at \([0-9.]*\) km/\1|\2|Re-anchor|\3% -> \4% at \5 km/' \ |
| 31 | + -e 's/.*\([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\)\.[0-9]*.* end_driving_session for \([^ ]*\) but no active session/\1|\2|Drive end|no active session/' \ |
| 32 | + -e 's/.*\([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\)\.[0-9]*.* Skipping learning for \([^ ]*\): \(.*\)/\1|\2|Skip learn|\3/' \ |
| 33 | + -e 's/.*\([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\)\.[0-9]*.* Learning for \([^ ]*\): \(.*\)/\1|\2|Learned|\3/' \ |
| 34 | + -e 's/.*\([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\)\.[0-9]*.* Ended driving session for \([^ ]*\): \(.*\)/\1|\2|Drive end|\3/' | |
| 35 | + grep '|' |
| 36 | +) | sort -t'|' -k1,1 | |
| 37 | +awk -F'|' 'BEGIN { |
| 38 | + print "| Time | VIN | Event | Details |" |
| 39 | + print "|------|-----|-------|---------|" |
| 40 | +} |
| 41 | +{ printf "| %s | %s | %s | %s |\n", $1, $2, $3, $4 }' |
0 commit comments