u/Skyfork

▲ 7 r/bmwz3

How much would it cost to pay someone to weld on a Randy Forbes kit?

My Z3 3.0 has failed welds/crack in the trunk and the diff mount is cracked. How much would a welder charge me to weld the kit on if I do all the prep work?

I can do it myself, but I'm tired boss.

reddit.com
u/Skyfork — 3 days ago

Screentime Lockdown Script for Kids

I've been playing with a RG40XXH and configuring it for my 5 year old's birthday present but there aren't any child screentime limitations built into the base system so I made my own. This is a service that can be activated by putting it into the /system/services/ directory and turning it on inside of system options.

Basic behavior:

Script keeps a background tally of screentime for the day. As time runs out, it changes the RGB stick colors from green to red, and then pulsing reg.

There's a voice that gives feedback every 15 minutes on how much time is left, then every minute, and every 15 seconds when you are less than 5 and 1 minute.

When time's up a 60 second shutdown timer starts, if you hit XYBA, it adds time to the timer.

If you don't, then the system shuts down.

Times reset the next calendar day.

I asked Gemini to annotate all code blocks so it shouldn't be too hard to figure out how to modify it to your children.

#!/bin/bash

# Persistent Screen Time Limit Service - With Voice Scheduling Log

# --- SCHEDULE CONFIGURATION (In Seconds) ---

LIMIT_MON=3600

LIMIT_TUE=3600

LIMIT_WED=3600

LIMIT_THU=3600

LIMIT_FRI=7200

LIMIT_SAT=10800

LIMIT_SUN=10800

# --- SYSTEM CONFIGURATION ---

DEBUG_MODE=0 # 1 for Debug/60x Speed, 0 for Normal

POLL_INTERVAL=10

TIME_MULTIPLIER=1

if [ "$DEBUG_MODE" -eq 1 ]; then

POLL_INTERVAL=1

TIME_MULTIPLIER=60

fi

DATA_FILE="/userdata/system/screentime.dat"

PID_FILE="/var/run/screentime.pid"

OVERRIDE_FILE="/tmp/screentime_override"

STATUS_LOG="/tmp/screentime_live.log"

INPUT_LOG="/tmp/screentime_inputs.log"

# Global persistent variables for logging

LAST_MSG="None"

NEXT_MSG="Calculating..."

get_daily_limit() {

DAY_INDEX=$(date +%u)

case "$DAY_INDEX" in

1) echo $LIMIT_MON ;; 2) echo $LIMIT_TUE ;; 3) echo $LIMIT_WED ;;

4) echo $LIMIT_THU ;; 5) echo $LIMIT_FRI ;; 6) echo $LIMIT_SAT ;;

7) echo $LIMIT_SUN ;; *) echo 3600 ;;

esac

}

start_sequence_listener() {

JS_EVENT=$(grep -E 'Name=|Handlers=|EV=' /proc/bus/input/devices | grep -A2 "Anbernic RG40XX-H" | grep -oE 'event[0-9]+' | head -n1)

[ -z "$JS_EVENT" ] && JS_EVENT="event1"

FULL_PATH="/dev/input/$JS_EVENT"

echo "Listener started on $JS_EVENT" > "$INPUT_LOG"

evtest "$FULL_PATH" 2>/dev/null | awk -v in_log="$INPUT_LOG" '

/type 1.*EV_KEY.*value 1/ {

if ($0 ~ /BTN_NORTH/) key = "X"

else if ($0 ~ /BTN_WEST|BTN_C/) key = "Y"

else if ($0 ~ /BTN_EAST/) key = "B"

else if ($0 ~ /BTN_SOUTH/) key = "A"

else key = "?"

history = history " " key

if (split(history, arr) > 5) {

history = ""

for (i=2; i<=6; i++) history = history " " arr[i]

}

print "Input History:" history > in_log

fflush(in_log)

seq = seq key

if (length(seq) > 4) seq = substr(seq, length(seq)-3)

if (seq == "XYBA") {

system("touch /tmp/screentime_override")

seq = ""

}

}' &

LISTENER_PID=$!

}

trigger_shutdown() {

rm -f "$OVERRIDE_FILE"

/usr/bin/knulli-rgb-led 2 100 255 0 0 255 0 0

for i in {60..1}; do

if [ -f "$OVERRIDE_FILE" ]; then

rm -f "$OVERRIDE_FILE"

read STORED_DATE ACCUM_SEC < "$DATA_FILE"

ACCUM_SEC=$((ACCUM_SEC - 900))

[ "$ACCUM_SEC" -lt 0 ] && ACCUM_SEC=0

echo "$STORED_DATE $ACCUM_SEC" > "$DATA_FILE"

espeak "Override accepted. 15 minutes added." 2>/dev/null &

/usr/bin/knulli-rgb-led 1 100 0 255 0 0 255 0

sleep 2

return 0

fi

if [ $((i % 10)) -eq 0 ]; then espeak "$i seconds left" 2>/dev/null &

elif [ $i -eq 5 ]; then espeak "See you tomorrow" 2>/dev/null & fi

echo "--- SHUTDOWN IMMINENT ---" > "$STATUS_LOG"

[ -f "$INPUT_LOG" ] && cat "$INPUT_LOG" >> "$STATUS_LOG"

echo "POWER OFF IN: $i seconds" >> "$STATUS_LOG"

sleep 1

done

/usr/bin/knulli-rgb-led 0

shutdown -h now

exit 0

}

monitor_time() {

start_sequence_listener

CURRENT_DATE=$(date +%F)

[ -f "$DATA_FILE" ] && read STORED_DATE ACCUM_SEC < "$DATA_FILE" || { STORED_DATE="$CURRENT_DATE"; ACCUM_SEC=0; }

LAST_SPOKEN_MIN="-1"

LAST_SPOKEN_REMAINING_MIN="-1"

while true; do

CURRENT_DATE=$(date +%F)

CURRENT_LIMIT=$(get_daily_limit)

[ "$CURRENT_DATE" != "$STORED_DATE" ] && { ACCUM_SEC=0; STORED_DATE="$CURRENT_DATE"; echo "$CURRENT_DATE 0" > "$DATA_FILE"; }

REMAINING_SEC=$((CURRENT_LIMIT - ACCUM_SEC))

[ "$REMAINING_SEC" -lt 0 ] && REMAINING_SEC=0

REMAINING_MIN=$((REMAINING_SEC / 60))

SEC_REMAINDER=$((REMAINING_SEC % 60))

# --- RGB LOGIC ---

if [ "$REMAINING_SEC" -gt 1800 ]; then

/usr/bin/knulli-rgb-led 1 100 0 255 0 0 255 0

LED_STATE="GREEN"

elif [ "$REMAINING_SEC" -le 300 ]; then

/usr/bin/knulli-rgb-led 2 100 255 0 0 255 0 0

LED_STATE="THROB"

else

RED_VAL=$(( 255 * (30 - REMAINING_MIN) / 25 ))

GREEN_VAL=$(( 255 - RED_VAL ))

/usr/bin/knulli-rgb-led 1 100 $RED_VAL $GREEN_VAL 0 $RED_VAL $GREEN_VAL 0

LED_STATE="FADE (${REMAINING_MIN}m)"

fi

# --- VOICE SCHEDULE LOGIC ---

CUR_MIN=$(date +%M)

CUR_TIME=$(date +%H:%M:%S)

# Calculate Next Event

if [ "$REMAINING_MIN" -lt 5 ]; then

NEXT_MSG="In $((60 - SEC_REMAINDER))s (1-min warning)"

elif [ "$REMAINING_MIN" -lt 30 ]; then

MIN_TO_NEXT=$(( REMAINING_MIN % 5 ))

[ "$MIN_TO_NEXT" -eq 0 ] && MIN_TO_NEXT=5

NEXT_MSG="In ${MIN_TO_NEXT}m (5-min warning)"

else

MIN_TO_NEXT=$(( 15 - (10#$CUR_MIN % 15) ))

NEXT_MSG="At :$(( (10#$CUR_MIN + MIN_TO_NEXT) % 60 )) (RTC Sync)"

fi

# --- LIVE DASHBOARD ---

{

echo "--- SCREENTIME STATUS ---"

echo "Time: $CUR_TIME | Remaining: $REMAINING_MIN min $SEC_REMAINDER sec"

echo "LED: $LED_STATE"

echo "Last Voice: $LAST_MSG"

echo "Next Voice: $NEXT_MSG"

[ -f "$INPUT_LOG" ] && cat "$INPUT_LOG"

[ "$DEBUG_MODE" -eq 1 ] && echo "MODE: DEBUG (60x Speed)" || echo "MODE: NORMAL"

} > "$STATUS_LOG"

# --- AUDIO EXECUTION ---

if [ "$DEBUG_MODE" -eq 1 ]; then

espeak "$REMAINING_MIN minutes and $SEC_REMAINDER seconds remaining" 2>/dev/null &

LAST_MSG="$REMAINING_MIN min $SEC_REMAINDER sec debug alert"

else

if [ "$CUR_MIN" != "$LAST_SPOKEN_MIN" ]; then

SPEAK_MSG=""

if [ "$REMAINING_MIN" -lt 5 ] && [ "$REMAINING_MIN" -gt 0 ]; then

SPEAK_MSG="You have $REMAINING_MIN minutes remaining"

elif [ "$REMAINING_MIN" -lt 30 ] && [ $((REMAINING_MIN % 5)) -eq 0 ] && [ "$REMAINING_MIN" -gt 0 ]; then

SPEAK_MSG="You have $REMAINING_MIN minutes remaining"

elif [ $((10#$CUR_MIN % 15)) -eq 0 ]; then

SPEAK_MSG="You have $REMAINING_MIN minutes remaining today"

fi

if [ -n "$SPEAK_MSG" ]; then

espeak "$SPEAK_MSG" 2>/dev/null &

LAST_MSG="[$CUR_TIME] \"$SPEAK_MSG\""

fi

LAST_SPOKEN_MIN=$CUR_MIN

fi

fi

if [ "$ACCUM_SEC" -ge "$CURRENT_LIMIT" ]; then

echo "$CURRENT_DATE $ACCUM_SEC" > "$DATA_FILE"

trigger_shutdown

fi

sleep $POLL_INTERVAL

ACCUM_SEC=$((ACCUM_SEC + (POLL_INTERVAL * TIME_MULTIPLIER) ))

LOOP_COUNT=$((LOOP_COUNT + 1))

[ $LOOP_COUNT -ge 6 ] && { echo "$CURRENT_DATE $ACCUM_SEC" > "$DATA_FILE"; LOOP_COUNT=0; }

done

}

case "$1" in

start) monitor_time & echo $! > "$PID_FILE" ;;

stop)

[ -f "$PID_FILE" ] && kill $(cat "$PID_FILE") 2>/dev/null

ps | grep evtest | grep -v grep | awk '{print $1}' | xargs kill 2>/dev/null

rm -f "$PID_FILE"

/usr/bin/knulli-rgb-led 0

;;

esac

reddit.com
u/Skyfork — 11 days ago