{{tag>[serial hardware linux]}} =====Smart Meter - P1 data logger===== This script will log serial data and prepend time/date stamp. The example below if P1 data from a smart meter. You can pipe this to [[rotatelogs]] to save the output to rotated logs. * Example output: # /usr/local/bin/serialWatch.exp ttyUSB0 2014-06-16,21:25:44 Log starting... spawn [open ...] 2014-06-16,21:25:45: 0 2014-06-16,21:25:45: /XMX5XMXABCE000046867 2014-06-16,21:25:45: 2014-06-16,21:25:45: 0-0:96.1.1(31333430303738362020202020202020) 2014-06-16,21:25:45: 1-0:1.8.1(05062.220*kWh) 2014-06-16,21:25:45: 1-0:1.8.2(04235.032*kWh) 2014-06-16,21:25:45: 1-0:2.8.1(00000.000*kWh) 2014-06-16,21:25:45: 1-0:2.8.2(00000.000*kWh) 2014-06-16,21:25:45: 0-0:96.14.0(0002) 2014-06-16,21:25:45: 1-0:1.7.0(0000.75*kW) 2014-06-16,21:25:45: 1-0:2.7.0(0000.00*kW) 2014-06-16,21:25:45: 0-0:17.0.0(999*A) 2014-06-16,21:25:45: 0-0:96.3.10(1) 2014-06-16,21:25:45: 0-0:96.13.1() 2014-06-16,21:25:45: 0-0:96.13.0() 2014-06-16,21:25:45: 0-1:96.1.0(3238303131303038323335313030333132) 2014-06-16,21:25:45: 0-1:24.1.0(03) 2014-06-16,21:25:45: 0-1:24.3.0(140616210000)(08)(60)(1)(0-1:24.2.0)(m3) 2014-06-16,21:25:45: (02418.609) 2014-06-16,21:25:45: 0-1:24.4.0(1) 2014-06-16,21:25:45: ! * Log and timestamp script: #! /bin/sh # the next line restarts using expect \ exec expect $0 ${1+"$@"} #!/usr/bin/expect -f # # serialWatch.exp # Connect up to a device on a serial port # Time stamp any incoming lines to stdout # port is any serial port (omit the /dev/ prefix) # e.g. ttya, cua0, serialA, serialB, boca01 - boca16 if {$argc != 1} { puts "$argc, $argv" puts "usage: serial.exp port" exit } proc timeStamp {} { global tcl_version if {$tcl_version >= 7.5} { # "clock" command requires Tcl v7.5 or greater # internal routine a little faster than making a system call set stamp [clock format [clock seconds] -format %Y-%m-%d,%T] } else { # fall back to standard UNIX system call set stamp [exec /bin/date +%Y-%m-%d,%T] } return $stamp } puts "\n[timeStamp] Log starting..." set port /dev/$argv set spawned [spawn -open [open $port w+]] puts "[timeStamp]: [string trim $spawned \r\n]" set baud 9600 # -parenb means don't use a parity bit # -cstopb means "not 2 stop bits, but 1" # cs8 means 8 bits # -echo means no echo (full duplex?) stty ispeed $baud ospeed $baud raw -echo cs7 parenb -parodd -cstopb onlcr < $port log_user 0 # log each input line # add a timeStamp at the beginning of each line while {1} { expect "\n" { puts "[timeStamp]: [string trim $expect_out(buffer) \r\n]" } } * Start logging after boot. Add to **/etc/rc.local**: echo "nohup /usr/local/bin/serialWatch.exp ttyUSB0 | rotatelogs -f /mnt/ram/p1data 86400 100M &" | at now+1min =====rsync / init script===== You can use the following script to sync the RAM disk to NAS. It wil also sync before shutdown. This has been tested on Raspbian (Raspberry PI) Debian. * Create script **/etc/init.d/rsync-p1-data**#!/bin/bash # # chkconfig: - 95 05 ### BEGIN INIT INFO # Provides: rsync-p1-data # Required-Stop: $network $local_fs $remote_fs # Required-Start: $syslog # Default-Start: 2 # Default-Stop: 0 1 6 # Short-Description: sync RAM disk to NAS # Description: rsync network captures from RAM disk to NAS ### END INIT INFO prog=`basename $0` lockfile=/var/lock/$prog ramdisk=/mnt/ram nas=/mnt/pd-p1smartmeter stop() { [ "$EUID" != "0" ] && exit 4 echo -n $"$prog, syncing RAM disk to NAS before shutdown." echo " ---- STOP runlevel: `/sbin/runlevel` date: `date`" >> /var/log/rsync.log /usr/bin/rsync --quiet -a --log-file=/var/log/rsync.log $ramdisk/ $nas RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f $lockfile return $RETVAL } start() { [ "$EUID" != "0" ] && exit 4 echo -n $"$prog, sync not needed at start-up." echo " ---- START runlevel: `/sbin/runlevel` date: `date`" >> /var/log/rsync.log RETVAL=$? echo [ $RETVAL -eq 0 ] && touch $lockfile return $RETVAL } sync() { [ "$EUID" != "0" ] && exit 4 # Sync all files but last (the one open for writing) to nas dir and year/day subdirs. # remove source files from RAM disk, if sync was succesful. # first create directory structure mkdir -p $nas/`date +%Y/%m/%d` # sync files ls $ramdisk | sort -t. -k2 | head -n -1 | /usr/bin/rsync --quiet -a --remove-source-files --log-file=/var/log/rsync.log --files-from=- $ramdisk/ $nas/`date +%Y/%m/%d` RETVAL=$? return $RETVAL } # See how we were called. case "$1" in stop) stop ;; start) start ;; sync) sync ;; *) echo $"Usage: $0 {start|stop|sync}" exit 2 esac * Enable script to run at stop/start update-rc.d rsync-p1-data defaults update-rc.d rsync-p1-data enable * Enable automatic sync every hour. Add to crontab: 1 * * * * /etc/init.d/rsync-p1-data sync