Commit f7dc5d36 authored by Mikhail Karpenko's avatar Mikhail Karpenko
Browse files

Add temperature monitoring script

parent fc532ce4
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@ IMAGE_INSTALL_append += " python-core \
                         libsjs \
                         smartmontools \
                         libogg \
                         init-elphel393 \
                         apps-camogm \
                         apps-imgsrv \
                         iw \
@@ -39,6 +38,7 @@ IMAGE_INSTALL_append += " python-core \
                         dhcp-client \
                         linux-firmware-rtl8192cu \
                         init-elphel393 \
                         init-tempmon \
                        "
                        
#kernel-modules
+1499 −0

File added.

Preview size limit exceeded, changes collapsed.

+45 −0
Original line number Diff line number Diff line
#!/bin/sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/init_tempmon
NAME=init_tempmon
DESC="temperature monitor daemon"

MNTPOINT=/mnt/mmc
MMCDEV=/dev/mmcblk0p1
SOME_SCRIPT=init_tempmon.py

case "$1" in
  start)
	echo -n "Starting $DESC: "
	if [ -f $MNTPOINT/$SOME_SCRIPT ]; then
	    echo "    Launching $SOME_SCRIPT"
	    $MNTPOINT/$SOME_SCRIPT
	else
	    echo "    $SOME_SCRIPT not found. Nothing to launch."
	fi
	;;
  stop)
	echo -n "Stopping $DESC: "
	echo "$NAME."
	;;
  restart)
	echo -n "Restarting $DESC: "
	echo "$NAME."
	;;
  status)
	echo -n "$NAME status:"
	if [ -f /var/run/$NAME ]; then
	  echo -n "Running"
	else
	  echo -n "Not running"
	fi
	;;
  *)
	N=/etc/init.d/$NAME
	echo "Usage: $N {start|stop|restart|status}" >&2
	exit 1
	;;
esac

exit 0 
+171 −0
Original line number Diff line number Diff line
#!/usr/bin/env python
# encoding: utf-8
'''
# Temperature monitor for Elphel393 camera.
# This python script should be started as a daemon at startup. It will continuously monitor
# camera temperature and turn external fan on and off. It will also turn camera off in case
# of extreme temperature limit is exceeded.
#
# Copyright (C) 2016, Elphel.inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
'''

import os
import sys
import time
import subprocess
from posix import EX_OSFILE, F_OK

DEBUG = 0

""" Set temperature when the fan should be turned on. """
TEMP_FAN_ON = 35.0
""" Set temperature when the system should be turned off. """
TEMP_SHUTDOWN = 60.0
""" Temperature hysteresis in degrees. """
TEMP_HYSTERESIS = 2.0
""" Temperature sampling time in seconds. This constant may be a floating point value. """ 
SAMPLING_TIME = 1
""" Temperature scaling factor. """
SCALE_CFT = 0.001

ctrl_path_pref = "/sys/devices/soc0/elphel393-pwr@0/"
ctrl_fn = {"poweroff_fn": "power_off",
           "vp5_en_fn":   "channels_en",
           "vp5_dis_fn":  "channels_dis",
           "gpio_fn":     "gpio_10389"}
hwmon_path_pref = "/sys/devices/soc0/amba@0/f8007100.ps7-xadc/iio:device0/"
hwmon_fn = {"offset": "in_temp0_offset",
            "raw":    "in_temp0_raw",
            "scale":  "in_temp0_scale"}
out_path_pref = "/var/volatile/tmp/"
out_fn = {"core_temp_fn": "core_temp"}

class temp_monitor():
    def __init__(self, ctrl_path_pref, ctrl_file_names, hwmon_path_pref, hwmon_fn,
                 out_path_prefix, out_fnames):
        self.is_fan_on = False
        self.is_vp5_enabled = False
        self.ctrl_path_prefix = ctrl_path_pref
        self.ctrl_fnames = ctrl_file_names
        self.hwmon_path_prefix = hwmon_path_pref
        self.hwmon_fnames = hwmon_fn
        self.samples_window = []
        """ Number of samples for temperature averaging """
        self.samples_num = 5
        self.fan_cmd = {"fan_cmd_on":  "0x101",
                        "fan_cmd_off": "0x100"}
        
        """ Create output files """
        try:
            self.core_temp_out_f = open(out_path_prefix + out_fnames["core_temp_fn"], "w")
        except IOError:
            print "Failed to create file: '%s%s'" % (out_path_prefix, out_fnames["core_temp_fn"])
        
    def check_files(self):
        """
        Check if all files exist in the system.
        """
        for key, val in self.hwmon_fnames.items():
            if not os.access(self.hwmon_path_prefix + val, F_OK):
                print "Failed to open sysfs file: '%s%s'" % (self.hwmon_path_prefix, val)
                return False
        for key, val in self.ctrl_fnames.items():
            if not os.access(self.ctrl_path_prefix + val, F_OK):
                print "Failed to open sysfs file: '%s%s'" % (self.ctrl_path_prefix, val)
                return False
        return True
                
    def shutdown(self):
        """
        Turn system off. This function will be called continuously until the system is turn off.
        """
        subprocess.call(["/sbin/shutdown", "-hP", "now"])        
    
    def fan_ctrl(self, ctrl):
        """
        Control fan by writing to sysfs files.
        @param ctrl: can be "on" or "off" to turn fan on or off
        """
        if ctrl is "on":
            with open(self.ctrl_path_prefix + self.ctrl_fnames["vp5_en_fn"], "r+") as f:
                """ check if +5V is active and turn it on if it is not (it should not happen) """
                channels = f.read()
                if channels.find("vp5") == -1:
                    f.write("vp5")
                    f.flush()
            with open(self.ctrl_path_prefix + self.ctrl_fnames["gpio_fn"], 'w') as f:
                f.write(self.fan_cmd["fan_cmd_on"])
                f.flush()
            self.is_fan_on = True
        elif ctrl is "off":
            with open(self.ctrl_path_prefix + self.ctrl_fnames["gpio_fn"], 'w') as f:
                f.write(self.fan_cmd["fan_cmd_off"])
                f.flush()
            self.is_fan_on = False
        else:
            print "'%s': unrecognized command: '%s'" % (__name__, ctrl)
    
    def monitor(self):
        """
        Continuously read temperature and control fan.
        """
        try:
            while True:
                with open(self.hwmon_path_prefix + self.hwmon_fnames["offset"]) as f:
                    offset = float(f.read().strip())
                with open(self.hwmon_path_prefix + self.hwmon_fnames["raw"]) as f:
                    raw = float(f.read().strip())
                with open(self.hwmon_path_prefix + self.hwmon_fnames["scale"]) as f:
                    scale = float(f.read().strip())
                
                if raw > 4000:
                    raw -= 4096
                core_temp = (raw + offset) * scale * SCALE_CFT
                self.samples_window.append(core_temp)
                if len(self.samples_window) > self.samples_num:
                    self.samples_window.pop(0)
                samples = list(self.samples_window)
                samples.sort()

                avg = samples[len(samples) / 2]
                if core_temp < (TEMP_FAN_ON - TEMP_HYSTERESIS) and self.is_fan_on:
                    self.fan_ctrl("off")
                elif core_temp >= TEMP_FAN_ON and core_temp < TEMP_SHUTDOWN and not self.is_fan_on:
                    self.fan_ctrl("on")
                elif avg >= TEMP_SHUTDOWN:
                    self.shutdown()
                
                self.core_temp_out_f.seek(0)
                self.core_temp_out_f.write(str(core_temp))
                self.core_temp_out_f.flush()
                
                print "Core temperature: '%f', median: '%f'" % (core_temp, avg)
                time.sleep(SAMPLING_TIME)
        except (KeyboardInterrupt, SystemExit):
            print "Got keyboard interrupt. Exiting."
            sys.exit(0)

if __name__ == "__main__":
    if DEBUG:
        ctrl_path_pref = ""
        hwmon_path_pref = ""
        out_path_pref = ""
    tm = temp_monitor(ctrl_path_pref, ctrl_fn, hwmon_path_pref, hwmon_fn, out_path_pref, out_fn)
    if tm.check_files():
        tm.monitor()
    else:
        sys.exit(1)
                
 No newline at end of file
+55 −0
Original line number Diff line number Diff line
SUMMARY = "Extra initscripts for the Elphel 10393 board"
DESCRIPTION = "Simple camera temperature monitor"

AUTHOR = "Elphel Inc."
HOMEPAGE = "http://www3.elphel.com/"

PRIORITY = "optional"
LICENSE = "GPLv3"
LIC_FILES_CHKSUM = "file://LICENSE;beginline=21;endline=699;md5=ccd2fef7dee090f3b211c6677c3e34cc"

SRCDATE = "20160516"

PV = "${SRCDATE}"
PR = "r0"

SRC_URI = "file://init_tempmon \
           file://init_tempmon.py \
           file://LICENSE \
          "

S = "${WORKDIR}/"

INITSCRIPT_NAME = "init_tempmon"
INITSCRIPT_PARAMS = "defaults 96"

RDEPENDS_${PN} += "python-core"

FILES_${PN} = "\
           /etc/* \
           /usr/* \
          "

#This needs to get the script into rc?.d/
inherit update-rc.d

do_install_append() {
    install -d ${D}${sysconfdir}/init.d
    install -m 0755 ${WORKDIR}/init_tempmon ${D}${sysconfdir}/init.d

    for RLOC in ${PRODUCTION_ROOT_LOCATION}; do
        if [ ! -d ${DEPLOY_DIR_IMAGE}/${RLOC} ]; then
            mkdir -p ${DEPLOY_DIR_IMAGE}/${RLOC}
        fi
        if [ -f ${S}init_tempmon.py ]; then
            if [ -f ${DEPLOY_DIR_IMAGE}/${RLOC}/init_tempmon.py ]; then
                rm ${DEPLOY_DIR_IMAGE}/${RLOC}/init_tempmon.py
            fi
            cp ${S}init_tempmon.py ${DEPLOY_DIR_IMAGE}/${RLOC}/init_tempmon.py
        else
            echo "NOT 3 FOUND!"
        fi
    done
}

PACKAGES = " init-tempmon"