only run convertion on solar power or sufficient battery
This commit is contained in:
@ -8,34 +8,81 @@ import sys
|
||||
from pathlib import Path
|
||||
|
||||
PROM_URL = "http://127.0.0.1:9104/metrics"
|
||||
MIN_SOC = 0.5 # 50%
|
||||
MIN_SOLAR_POWER = 500 # 500W
|
||||
|
||||
def load_config(path):
|
||||
"""Load JSON configuration file."""
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
|
||||
def wait_for_solar_power():
|
||||
import requests
|
||||
import time
|
||||
|
||||
def wait_for_solar_power(prom_url, check_interval=300, max_retries=None):
|
||||
"""
|
||||
Wait until the Prometheus metric `fronius_site_autonomy_ratio` equals 1.0.
|
||||
Check every 5 minutes if not available.
|
||||
Wait until:
|
||||
- fronius_site_power_photovoltaic > 500
|
||||
- fronius_inverter_soc{inverter="1"} > 0.5
|
||||
|
||||
Args:
|
||||
prom_url (str): Prometheus metrics endpoint.
|
||||
check_interval (int): Seconds between checks (default: 300).
|
||||
max_retries (int or None): Optional limit on checks. If None, loop indefinitely.
|
||||
|
||||
Returns:
|
||||
bool: True if conditions met, False if retries exhausted.
|
||||
"""
|
||||
attempts = 0
|
||||
while True:
|
||||
try:
|
||||
r = requests.get(PROM_URL, timeout=5)
|
||||
if r.status_code == 200:
|
||||
for line in r.text.splitlines():
|
||||
if line.startswith("fronius_site_autonomy_ratio"):
|
||||
try:
|
||||
value = float(line.split()[-1])
|
||||
if value == 1.0:
|
||||
print("[INFO] Solar power available – starting conversion.")
|
||||
return
|
||||
except ValueError:
|
||||
pass
|
||||
print("[INFO] No solar power – waiting 5 minutes...")
|
||||
r = requests.get(prom_url, timeout=5)
|
||||
r.raise_for_status()
|
||||
|
||||
pv_power = None
|
||||
inverter_soc = None
|
||||
|
||||
for line in r.text.splitlines():
|
||||
if line.startswith("#"): # Skip comments and HELP/TYPE lines
|
||||
continue
|
||||
parts = line.split()
|
||||
if len(parts) != 2:
|
||||
continue
|
||||
|
||||
metric, value_str = parts
|
||||
try:
|
||||
value = float(value_str)
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
if metric == "fronius_site_power_photovoltaic":
|
||||
pv_power = value
|
||||
elif (
|
||||
metric.startswith("fronius_inverter_soc")
|
||||
and '{inverter="1"}' in metric
|
||||
):
|
||||
inverter_soc = value
|
||||
|
||||
if pv_power is not None and inverter_soc is not None:
|
||||
if pv_power > MIN_SOLAR_POWER and inverter_soc > MIN_SOC:
|
||||
print(
|
||||
f"[INFO] Solar power available: PV={pv_power:.2f} W, SOC={inverter_soc:.2f} – starting conversion."
|
||||
)
|
||||
return True
|
||||
|
||||
print(
|
||||
f"[INFO] Conditions not met (PV={pv_power}, SOC={inverter_soc}). Waiting {check_interval} seconds..."
|
||||
)
|
||||
|
||||
except requests.RequestException as e:
|
||||
print(f"[WARN] Could not reach Prometheus: {e}")
|
||||
time.sleep(300) # Wait 5 minutes
|
||||
|
||||
attempts += 1
|
||||
if max_retries is not None and attempts >= max_retries:
|
||||
print("[ERROR] Max retries reached. Exiting without solar power.")
|
||||
return False
|
||||
|
||||
time.sleep(check_interval)
|
||||
|
||||
def analyze_codecs(oldfile, newfile, dst_folder):
|
||||
"""
|
||||
@ -87,25 +134,41 @@ def main():
|
||||
print(f"[INFO] Skip {dst_file}, already exists. --> Convert already done!")
|
||||
continue
|
||||
|
||||
wait_for_solar_power()
|
||||
wait_for_solar_power(PROM_URL)
|
||||
|
||||
try:
|
||||
cmd = [
|
||||
"taskset", "-c", "0,1,2,3", # limit to first 4 CPU cores
|
||||
"ffmpeg", "-i", str(src_file),
|
||||
"-c:v", "libaom-av1",
|
||||
"-c:a", "libopus",
|
||||
"-mapping_family", "1",
|
||||
"-af", "aformat=channel_layouts=5.1",
|
||||
"-c:s", "copy",
|
||||
"-map", "0",
|
||||
"-crf", "24",
|
||||
"-b:v", "0",
|
||||
"-b:a", "128k",
|
||||
"-cpu-used", "4",
|
||||
"-row-mt", "1",
|
||||
"-tiles", "2x2",
|
||||
str(tmp_dst_file)
|
||||
"taskset",
|
||||
"-c",
|
||||
"0,1,2,3", # limit to first 4 CPU cores
|
||||
"ffmpeg",
|
||||
"-i",
|
||||
str(src_file),
|
||||
"-c:v",
|
||||
"libaom-av1",
|
||||
"-c:a",
|
||||
"libopus",
|
||||
"-mapping_family",
|
||||
"1",
|
||||
"-af",
|
||||
"aformat=channel_layouts=5.1",
|
||||
"-c:s",
|
||||
"copy",
|
||||
"-map",
|
||||
"0",
|
||||
"-crf",
|
||||
"24",
|
||||
"-b:v",
|
||||
"0",
|
||||
"-b:a",
|
||||
"128k",
|
||||
"-cpu-used",
|
||||
"4",
|
||||
"-row-mt",
|
||||
"1",
|
||||
"-tiles",
|
||||
"2x2",
|
||||
str(tmp_dst_file),
|
||||
]
|
||||
print(f"[CMD] {' '.join(cmd)}")
|
||||
subprocess.run(cmd, check=True)
|
||||
@ -119,6 +182,5 @@ def main():
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"[ERROR] Processing failed for {job}: {e}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
Reference in New Issue
Block a user