Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
slowrunner committed Mar 18, 2024
1 parent 8067fd7 commit 987bf09
Show file tree
Hide file tree
Showing 6 changed files with 345 additions and 0 deletions.
28 changes: 28 additions & 0 deletions config/crontab-e
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
@reboot sleep 10 && /usr/bin/python3 /home/pi/GoPi5Go/plib/cleanlifelog.py
@reboot sleep 15 && /home/pi/GoPi5Go/utils/nohup_loglife.sh
0 * * * * /usr/bin/python3 /home/pi/GoPi5Go/plib/cleanlifelog.py


87 changes: 87 additions & 0 deletions plib/cleanlifelog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/usr/bin/env python3
#
# cleanlifelog.py
#
# save life.log to life.log.timestamp
# read life.log file into list
# starting at next to last line
# loop until "boot logged line"
# if line is an execution log line: delete it
# else point to previous line
# write out modified file

import datetime
from shutil import copyfile
import argparse


dtNow = datetime.datetime.now()

HOME = "GoPi5Go"
inFileName = "/home/pi/"+HOME+"/logs/life.log"
outFileName = "/home/pi/"+HOME+"/logs/life.log"
bkupFileName = "/home/pi/"+HOME+"/logs/life.log.bak"

# Uncomment these to test in ~/Carl/Projects/CleanLifeLog/
# inFileName = "life.log.test"
# outFileName = "life.log.new"
# bkupFileName = "life.log.bkup_"+dtNow.strftime("%Y%m%d_%H%M%S")

# ARGUMENT PARSER
ap = argparse.ArgumentParser()
# ap.add_argument("-f", "--file", required=True, help="path to input file")
# ap.add_argument("-n", "--num", type=int, default=5, help="number")
ap.add_argument("-p", "--previous", default=False, action='store_true', help="clean previous boot session")
args = vars(ap.parse_args())
# print("Started with args:",args)
clean_previous_session = args['previous']



changed = False

with open(inFileName) as fIn:
lineList = fIn.readlines()
print("Read in {}".format(inFileName))
lines = len(lineList)
lineIdx = lines - 1
last = -1
print("lines: {}".format(lines))
print("lastline: {}".format(lineList[last]))
bootlogline = "----- boot -----"
executionlogline = "dEmain execution:"

if (clean_previous_session == True):
# Find last boot log line
while (bootlogline not in lineList[lineIdx]):
lineIdx -=1
lineIdx -=1

# Find last execution log line before the last boot log line
while ((bootlogline not in lineList[lineIdx]) and (executionlogline not in lineList[lineIdx])):
lineIdx -= 1

# leave the last execution log line
if (executionlogline in lineList[lineIdx]):
lineIdx -= 1

while (bootlogline not in lineList[lineIdx]):
# print("Checking line {}".format(lineIdx+1))
if (executionlogline in lineList[lineIdx]):
print("removing: {}".format(lineList[lineIdx]))
del lineList[lineIdx]
changed = True
lineIdx -= 1

if changed == True:
# backup the original file before rewriting with changes
copyfile(inFileName, bkupFileName)
with open(outFileName,'w') as fOut:
fOut.writelines(lineList)

print("Wrote cleaned {}".format(outFileName))
lines = len(lineList)
print("lines: {}".format(lines))
print("lastline: {}".format(lineList[last]))
else:
print("File not changed")
55 changes: 55 additions & 0 deletions plib/lifeLog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/python3
#
# lifeLog.py allow user scripts to
# log to life.log
#
# Formats message as:
# YYYY-MM-DD HH:MM|[<script.py>.<funcName>]<message>
#
# USAGE:
# import sys
# sys.path.append('/home/pi/HOME/plib')
# import lifeLog
#
#
# def somefunc():
# strToLog = "message"
# lifeLog.logger.info(strToLog) or
# lifeLog.logger.info("message")
#

from __future__ import print_function

import sys
import logging

HOME="GoPi5Go"
# create logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

loghandler = logging.FileHandler('/home/pi/"+HOME+"/logs/life.log')

logformatter = logging.Formatter('%(asctime)s|[%(filename)s.%(funcName)s]%(message)s',"%Y-%m-%d %H:%M")
loghandler.setFormatter(logformatter)
logger.addHandler(loghandler)



def testfunc():
strToLog = "---- lifeLog.py testfunc() executed"
logger.info(strToLog)
print("lifeLog.py testfunc() logged:",strToLog)

# test main
def main():

testfunc()


if __name__ == "__main__":
main()




129 changes: 129 additions & 0 deletions plib/loglife.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#!/usr/bin/env python3
#
# loglife.py digital entity to log each three minutes of life
# to life.log
#
# with sudo crontab -e
# @reboot /home/pi/GoPi5Go/utils/nohup_loglife.py
# touch /home/pi/GoPi5Go/logs/life.log
# chmod 777 /home/pi/GoPi5Go/logs/life.log
#

import time
import sys
sys.path.insert(1,"/home/pi/GoPi5Go/plib/")
import multiprocessing
import logging
import traceback
import signal
# from noinit_easygopigo3 import EasyGoPiGo3
# import battery

# create logger
logger = logging.getLogger('lifelog')
logger.setLevel(logging.INFO)
loghandler = logging.FileHandler('/home/pi/GoPi5Go/logs/life.log')
logformatter = logging.Formatter('%(asctime)s|%(message)s',"%Y-%m-%d %H:%M")
loghandler.setFormatter(logformatter)
logger.addHandler(loghandler)

debugLevel = 0

# ######### CNTL-C #####
# Callback and setup to catch control-C and quit program

_funcToRun=None

def signal_handler(signal, frame):
if debugLevel: print('\n** Control-C Detected')
if (_funcToRun != None):
_funcToRun()
sys.exit(0) # raise SystemExit exception

# Setup the callback to catch control-C
def set_cntl_c_handler(toRun=None):
global _funcToRun
_funcToRun = toRun
signal.signal(signal.SIGINT, signal_handler)


class digitalEntity():

# CLASS VARS (Avail to all instances)
# Access as X.class_var_name

pHandle=None # the SINGLE execution thread for the X class
defaultSleep=180.0 # sleep for 3 minutes by default

# end of class vars definition

def __init__(self,dEname,tSleep=defaultSleep): #run about once a minute
# SINGLETON TEST
if (digitalEntity.pHandle!=None):
if debugLevel: print("Second digitalEntity, not starting")
return None

# INITIALIZE CLASS INSTANCE

# START A Process
# process target must be an instance
digitalEntity.pHandle = multiprocessing.Process(name=dEname, target=self.dEmain,
args=(tSleep,))
digitalEntity.pHandle.start()
if debugLevel: print("%s.digitalEntity told to start" % dEname)
#end init()

# digitalEntity main process
def dEmain(self,tSleep=defaultSleep):
myname = multiprocessing.current_process().name
time.sleep(60) # wait for network date time sync
logger.info("------------ boot ------------")
if debugLevel: print("%s.dEmain started with tSleep=%f" % (myname,tSleep))
# logger.info('%s.dEmain started',myname)
# egpg = EasyGoPiGo3(use_mutex=True,noinit=True)
# logger.info(battery.voltages_string(egpg))
# del egpg
i=0
while True:
time.sleep(tSleep)
i+=0.05 # every three minutes is .05 hours
if debugLevel: print("%s.dEmain execution %.2f" % (myname,i))
logger.info('%s.dEmain execution: %.2f',myname, i )


if debugLevel: print("dEmain end reached")

def cancel(self):
myname = multiprocessing.current_process().name
if debugLevel: print("%s.cancel() called" % myname)
logger.info('%s.cancel() called',myname)
if debugLevel: print("\nWaiting for %s dE.workerThread to quit\n" % self.pHandle.name)
self.pHandle.join()
if debugLevel: print("%s.cancel() complete" % myname)


# ##### digitalEntity tt ######
#

def main():

tt=digitalEntity(dEname="lifelogger",tSleep=180) #create
set_cntl_c_handler(tt.cancel)

try:
while True:
if debugLevel: print("\n loglife.py: main()")
time.sleep(180)
#end while
except SystemExit:
if debugLevel: print("loglife.py: Bye Bye")
except:
if debugLevel: print("Exception Raised")
traceback.print_exc()

if __name__ == "__main__":
main()




4 changes: 4 additions & 0 deletions utils/nohup_loglife.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

nohup /home/pi/GoPi5Go/plib/loglife.py >/dev/null 2>&1 &

42 changes: 42 additions & 0 deletions utils/totallife.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash
#
# totallife.sh print total hours and sessions of life in life.log
#
# requires bc (sudo apt-get install bc)
#
# Counted Keys:
# Playtimes: " Docking: success "
# Sessions: "- boot -" ( "\- boot \-" search string )
# Safety shutdowns: "safety shutdown"

echo "(Cleaning life.log first)"
/home/pi/GoPi5Go/plib/cleanlifelog.py
echo " "
fn="/home/pi/GoPi5Go/logs/life.log"
ofn='/home/pi/GoPi5Go/logs/odometer.log'
# fn="/home/pi/wali_pi5/utils/test_life.log"
# totalAwake=`(awk -F':' '{sum+=$3}END{print sum;}' $fn)`
totalAwake=`(awk -F'execution:' '{sum+=$2}END{print sum;}' $fn)`
totalNaps=`(awk -F'nap for' '{sum+=$2}END{print sum;}' $fn)`
totalLife=`(echo "scale=1; ($totalAwake + $totalNaps)" | bc)`
echo "*** GoPi5Go TOTAL LIFE STATISTICS ***"
echo "Total Awake: " $totalAwake " hrs"
echo "Total Naps: " $totalNaps " hrs"
echo "Total Life: " $totalLife " hrs (since Dec 11, 2023)"
# echo "Playtimes (Undocked-Docked):" `(grep -c " Docking: success " $fn)`
# last5playtimes=`(grep " hrs playtime " $fn | tail -5 | awk -F" after " '{sum+=$2}END{print sum;}' )`
# last5avePlaytime=`(echo "scale=1; $last5playtimes / 5" | bc)`
# echo "Average playtime (last five)" $last5avePlaytime "hrs "
# last5dockedtimes=`(grep " docked for " $fn | tail -5 | awk -F" for " '{sum+=$2}END{print sum;}' )`
# last5aveDockedtime=`(echo "scale=1; $last5dockedtimes / 5" | bc)`
# echo "Average docked time (last five)" $last5aveDockedtime "hrs "
booted=`(grep -c "\- boot \-" $fn)`
echo "Sessions (boot): " `(grep -c "\- boot \-" $fn)`
aveSession=`(echo "scale=1; ($totalAwake / $booted)" | bc -l)`
echo "Average Session: " $aveSession "hrs"
safetyShutdowns=`(grep -c "safety shutdown" $fn)`
echo "Safety Shutdowns: " $safetyShutdowns
totalMoved=`(awk -F'moved:' '{sum+=$2}END{printf "%.1f", sum;}' $ofn)`
totalMovedFt=`(echo "scale=1; ($totalMoved / 0.3048)" | bc)`
echo "Total Travel: " $totalMoved "meters" $totalMovedFt "feet"

0 comments on commit 987bf09

Please sign in to comment.