#!/usr/bin/env python3
#
# Log power parameters from the power PCB.
#
# Note: this requires pyserial.

import os, json
import argparse
import sys
from datetime import datetime

for _p in (
    os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'lib'),
    '/usr/lib/signalytic_bm',
):
    if os.path.isfile(os.path.join(_p, 'serial_console.py')):
        sys.path.insert(0, _p)
        break
from serial_console import open_console, BusyError

# command line
parser = argparse.ArgumentParser()
parser.add_argument("-c", "--console", help="write to console instead of bgsystemlog", action="store_true")
args = parser.parse_args()

# Send a command to running power manager
def send_command(s, command):
    command = command.strip()
    cmd = command+"\r"
    s.reset_output_buffer()
    s.reset_input_buffer()
    sz = s.write(cmd.encode())
    s.flush()
    for i in range(10):
        reply = s.readline().decode().strip()
        if reply and reply!=command: break
    return reply

if args.console:
  ts=datetime.now()
  print("time: {\"ts\": \"" + ts.strftime("%Y-%m-%d %H:%M:%S.%f") + "\"}")

# Log to stdout or blockgraph
def writelog(level, system, msg):
  if args.console:
    print(level + " " + system + " " + msg)
  else:
    os.system("bgsystemlog -l " + level + " -s " + system + " -m '" + msg + "'")

# Log data to stdout or blockgraph
def writedatalog(location, msg):
  if args.console:
    print(location + ": " + msg)
  else:
    os.system("bgsystemlog -j " + location + " -m '" + msg + "'")

# Open serial connection (skip silently if another process holds the console).
try:
    with open_console(contention='fail', timeout=4) as ser:
        # Connectivity check, clear buffer
        ser.reset_output_buffer()
        for i in range(10):
            reply = send_command(ser, "?")
            if reply=="OK": break
        if reply!="OK":
            writelog( 'ERROR', 'POWER', "init expected OK, received: "+reply)
            exit(1)

        reply = send_command(ser, "bmstatus -s")
        try:
            json_data = json.loads(reply)
        except:
            writelog( 'ERROR', 'POWER', f"log_powerpcb_status exception: {reply}")
        else:

            solar = {}
            mains = {}
            input_source = json_data['input_source']
            if input_source==1:
                solar['V_mV'] = json_data['input_voltage_mV']
                solar['I_mA'] = json_data['input_current_mA']
                solar['P_mW'] = json_data['input_power_mW']
                mains['V_mV'] = 0
                mains['I_mA'] = 0
                mains['P_mW'] = 0
            else:
                solar['V_mV'] = 0
                solar['I_mA'] = 0
                solar['P_mW'] = 0
                mains['V_mV'] = json_data['input_voltage_mV']
                mains['I_mA'] = json_data['input_current_mA']
                mains['P_mW'] = json_data['input_power_mW']
            writedatalog( 'solar',    json.dumps(solar) )
            writedatalog( 'mains',    json.dumps(mains) )
            battery = {}
            battery['V_mV'] = json_data['battery_voltage_mV']
            battery['I_mA'] = json_data['battery_current_mA']
            battery['SoC_pct'] = json_data['battery_soc_pct']
            writedatalog( 'battery',  json.dumps(battery) )
            load = {}
            load['V_mV'] = json_data['load_voltage_mV']
            load['I_mA'] = json_data['load_current_mA']
            load['P_mW'] = json_data['load_power_mW']
            writedatalog( 'poweruse', json.dumps(load) )
            temp = {}
            temp['Tbat_mC'] = json_data['temperature_battery_mC']
            temp['Tdevice_mC'] = json_data['temperature_device_mC']
            writedatalog( 'temperature', json.dumps(temp) )
except BusyError:
    sys.exit(0)
except FileNotFoundError as e:
    writelog( 'ERROR', 'POWER', f"log_powerpcb_status: {e}")
    sys.exit(1)
