Index: trunk/FACT++/munin/container_temp
===================================================================
--- trunk/FACT++/munin/container_temp	(revision 16760)
+++ trunk/FACT++/munin/container_temp	(revision 16760)
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+case $1 in
+   config)
+        cat <<'EOM'
+graph_title Container temperature
+graph_vlabel temperature
+graph_category environment
+container_temp.label temperature
+container_temp.warning 40
+container_temp.critical 45
+EOM
+        exit 0;;
+esac
+
+. /etc/munin/plugins/ticktick.sh
+
+DATA=`curl -s "http://10.0.100.234/statusjsn.js?components=18179&_=1365876572736"`
+
+RC=$?
+
+if [ "$RC" != "0" ] ; then
+     echo Could not fetch container temperature: curl returned $RC >&2
+     exit -1
+fi
+
+
+tickParse "$DATA"
+
+VAL=``sensor_values[0].values[0][0].v``
+MIN=``sensor_values[0].values[0][0].st[0]``
+MAX=``sensor_values[0].values[0][0].st[1]``
+
+echo container_temp.value $VAL
Index: trunk/FACT++/munin/ticktick.sh
===================================================================
--- trunk/FACT++/munin/ticktick.sh	(revision 16760)
+++ trunk/FACT++/munin/ticktick.sh	(revision 16760)
@@ -0,0 +1,368 @@
+#!/usr/bin/env bash
+
+ARGV=$@
+
+__tick_error() {
+  echo "TICKTICK PARSING ERROR: "$1
+}
+
+# This is from https://github.com/dominictarr/JSON.sh
+# See LICENSE for more info. {{{
+__tick_json_tokenize() {
+  local ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
+  local CHAR='[^[:cntrl:]"\\]'
+  local STRING="\"$CHAR*($ESCAPE$CHAR*)*\""
+  local VARIABLE="\\\$[A-Za-z0-9_]*"
+  local NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?'
+  local KEYWORD='null|false|true'
+  local SPACE='[[:space:]]+'
+  egrep -ao "$STRING|$VARIABLE|$NUMBER|$KEYWORD|$SPACE|." --color=never | egrep -v "^$SPACE$"  # eat whitespace
+}
+
+__tick_json_parse_array() {
+  local index=0
+  local ary=''
+
+  read -r Token
+
+  case "$Token" in
+    ']') ;;
+    *)
+      while :
+      do
+        __tick_json_parse_value "$1" "`printf "%012d" $index`"
+
+        (( index++ ))
+        ary+="$Value" 
+
+        read -r Token
+        case "$Token" in
+          ']') break ;;
+          ',') ary+=_ ;;
+          *) 
+            __tick_error "Array syntax malformed"
+            break ;;
+        esac
+        read -r Token
+      done
+      ;;
+  esac
+}
+
+__tick_json_parse_object() {
+  local key
+  local obj=''
+  read -r Token
+
+  case "$Token" in
+    '}') ;;
+    *)
+      while :
+      do
+        # The key, it should be valid
+        case "$Token" in
+          '"'*'"'|\$[A-Za-z0-9_]*) key=$Token ;;
+          # If we get here then we aren't on a valid key
+          *) 
+            __tick_error "Object without a Key"
+            break
+            ;;
+        esac
+
+        # A colon
+        read -r Token
+
+        # The value
+        read -r Token
+        __tick_json_parse_value "$1" "$key"
+        obj+="$key:$Value"        
+
+        read -r Token
+        case "$Token" in
+          '}') break ;;
+          ',') obj+=_ ;;
+        esac
+        read -r Token
+      done
+    ;;
+  esac
+}
+
+__tick_json_parse_value() {
+  local jpath="${1:+$1_}$2"
+  local prej=${jpath//\"/}
+
+  [ "$prej" ] && prej="_$prej"
+  [ "$prej" ] && prej=${prej/-/__hyphen__}
+
+  case "$Token" in
+    '{') __tick_json_parse_object "$jpath" ;;
+    '[') __tick_json_parse_array  "$jpath" ;;
+
+    *) 
+      Value=$Token 
+      Path="$Prefix$prej"
+      Path=${Path/#_/}
+      echo __tick_data_${Path// /}=$Value 
+      ;;
+  esac
+}
+
+__tick_json_parse() {
+  read -r Token
+  __tick_json_parse_value
+  read -r Token
+}
+# }}} End of code from github
+
+# Since the JSON parser is just json parser, and we have a runtime
+# and assignments built on to this, along with javascript like referencing
+# there is a two-pass system, just because it was easier to code.
+#
+# This one separates out the valid JSON from the runtime library support
+# and little fo' language that this is coded in.
+__tick_fun_tokenize_expression() {
+  CHAR='[0-9]*[A-Za-z_$\\][0-9]*'
+  FUNCTION="(push|pop|shift|items|delete|length)[[:space:]]*\("
+  NUMBER='[0-9]*'
+  STRING="$CHAR*($CHAR*)*"
+  PAREN="[()]"
+  QUOTE="[\"\']"
+  SPACE='[[:space:]]+'
+  egrep -ao "$FUNCTION|$STRING|$QUOTE|$PAREN|$NUMBER|$SPACE|." --color=never |\
+    sed "s/^/S/g;s/$/E/g" # Make sure spaces are respected
+}
+
+__tick_fun_parse_expression() {
+  while read -r token; do
+    token=${token/#S/}
+    token=${token/%E/}
+
+    if [ $done ]; then
+      suffix+="$token"
+    else
+      case "$token" in
+        #
+        # The ( makes sure that you can do key.push = 1, not that you would, but
+        # avoiding having reserved words lowers the barrier to entry.  Try doing
+        # say function debugger() {} in javascript and then run it in firefox. That's
+        # a fun one.
+        #
+        # So, it's probably better to be as lenient as possible when dealing with
+        # syntax like this.
+        #
+        'push('|'pop('|'shift('|'items('|'delete('|'length(') function=$token ;;
+        ')') 
+          function=${function/%(/}
+
+          #
+          # Since bash only returns integers, we have to have a significant hack in order
+          # to return a string and then do something to the object. Basically, everything
+          # gets slammed inline.
+          #
+          # Q: Why don't you just reserve a global and then have the subfunction assign to it?
+          #
+          # A: Because the assignment has to happen prior to the function running. There's a number
+          #    of syntax tricks where you can basically emulate "pointers", but then the coder would
+          #    have to know about this "pointer" idea and then deal with their variables a different
+          #    way.
+          #
+          # ---------
+          #
+          # Q: Why don't you just do stuff in a sub-shell and then make sure you emit things in 
+          #    something like a ( ) or a ` ` block?
+          #
+          # A: Because environments get copied into the subshell and then you'd be modifying the
+          #    copy, not the original data.  After the subshell ended, the original environment
+          #    would stay, unmodified.
+          #
+          # ---------
+          # 
+          # Q: Why don't you use the file system and do some magic with subthreads or something?
+          #
+          # A: Really? This should have side-effects? In programming there is something called
+          #    the principle of least astonishment. In a way, the implementation below somewhat
+          #    breaks that principle.  However, using a file system or doing something really 
+          #    funky like that, would violate that principle far more.
+          #
+          # ---------
+          #
+          # But really, I sincerely hate the current solution. If you have a better idea, please
+          # please, open a dialog with me.
+          #
+          case $function in
+            items) echo '${!__tick_data_'"$Prefix"'*}' ;;
+            delete) echo 'unset __tick_data_'${Prefix/%_/} ;;
+            pop) echo '"$( __tick_runtime_last ${!__tick_data_'"$Prefix"'*} )"; __tick_runtime_pop ${!__tick_data_'"$Prefix"'*}' ;;
+            shift) echo '`__tick_runtime_first ${!__tick_data_'"$Prefix"'*}`; __tick_runtime_shift ${!__tick_data_'"$Prefix"'*}' ;;
+            length) echo '`__tick_runtime_length ${!__tick_data_'"$Prefix"'*}`' ;;
+            *) echo "__tick_runtime_$function \"$arguments\" __tick_data_$Prefix "'${!__tick_data_'"$Prefix"'*}'
+          esac
+          unset function
+
+          return
+          ;;
+
+        [0-9]*[A-Za-z]*[0-9]*) [ -n "$function" ] && arguments+="$token" || Prefix+="$token" ;;
+
+        [0-9]*) Prefix+=`printf "%012d" $token` ;;
+        '['|.) Prefix+=_ ;;
+        '"'|"'"|']') ;;
+        =) done=1 ;;
+        # Only respect a space if its in the args.
+        ' ') [ -n "$function" ] && arguments+="$token" ;;
+        *) [ -n "$function" ] && arguments+="$token" || Prefix+="$token" ;;
+      esac
+    fi
+  done
+
+  if [ "$suffix" ]; then
+    echo "$suffix" | __tick_json_tokenize | __tick_json_parse
+  else
+    Prefix=${Prefix/-/__hyphen__}
+    echo '${__tick_data_'$Prefix'}'
+  fi
+}
+
+__tick_fun_parse_tickcount_reset() {
+  # If the tick count is 1 then the backtick we encountered was a 
+  # shell code escape. These ticks need to be preserved for the script.
+  if (( ticks == 1 )); then
+    code+='`'
+  fi
+
+  # This resets the backtick counter so that `some shell code` doesn't
+  # trip up the tokenizer
+  ticks=0
+}
+
+# The purpose of this function is to separate out the Bash code from the
+# special "tick tick" code.  We do this by hijacking the IFS and reading
+# in a single character at a time
+__tick_fun_parse() {
+  IFS=
+
+  # code oscillates between being bash or tick tick blocks.
+  code=''
+
+  # By using -n, we are given that a newline will be an empty token. We
+  # can certainly test for that.
+  while read -r -n 1 token; do
+    case "$token" in
+      '`') 
+
+        # To make sure that we find two sequential backticks, we reset the counter
+        # if it's not a backtick.
+        if (( ++ticks == 2 )); then
+
+          # Whether we are in the stanza or not, is controlled by a different
+          # variable
+          if (( tickFlag == 1 )); then
+            tickFlag=0
+            [ "$code" ] && echo -n "`echo $code | __tick_fun_tokenize_expression | __tick_fun_parse_expression`"
+          else
+            tickFlag=1
+            echo -n "$code"
+          fi
+
+          # If we have gotten this deep, then we are toggling between backtick
+          # and bash. So se should unset the code.
+          unset code
+        fi
+        ;;
+
+      '') 
+        __tick_fun_parse_tickcount_reset
+
+        # this is a newline. If we are in ticktick, then we want to consume
+        # them for the parser later on. If we are in bash, then we want to
+        # preserve them.  We do this by emitting our buffer and then clearing
+        # it
+        if (( tickFlag == 0 )); then
+          echo "$code"
+          unset code
+        fi
+
+        ;;
+
+      *) 
+        __tick_fun_parse_tickcount_reset
+        
+        # This is a buffer of the current code, either bash or backtick
+        code+="$token"
+        ;;
+    esac 
+  done
+}
+
+__tick_fun_tokenize() {
+  # This makes sure that when we rerun the code that we are
+  # interpreting, we don't try to interpret it again.
+  export __tick_var_tokenized=1
+
+  # Using bash's caller function, which is for debugging, we
+  # can find out the name of the program that called us. We 
+  # then cat the calling program and push it through our parser
+  local code=$(cat `caller 1 | cut -d ' ' -f 3` | __tick_fun_parse)
+
+  # Before the execution we search to see if we emitted any parsing errors
+  hasError=`echo "$code" | grep "TICKTICK PARSING ERROR" | wc -l`
+
+  if [ $__tick_var_debug ]; then
+    printf "%s\n" "$code"
+    exit 0
+  fi
+
+  # If there are no errors, then we go ahead
+  if (( hasError == 0 )); then
+    # Take the output and then execute it
+
+    bash -c "$code" -- $ARGV
+  else
+    echo "Parsing Error Detected, see below"
+
+    # printf observes the new lines
+    printf "%s\n" "$code"
+    echo "Parsing stopped here."
+  fi
+
+  exit
+}
+
+## Runtime {
+__tick_runtime_length() { echo $#; }
+__tick_runtime_first() { echo ${!1}; }
+__tick_runtime_last() { eval 'echo $'${!#}; }
+__tick_runtime_pop() { eval unset ${!#}; }
+
+__tick_runtime_shift() {
+  local left=
+  local right=
+
+  for (( i = 1; i <= $# + 1; i++ )) ; do
+    if [ "$left" ]; then
+      eval "$left=\$$right"
+    fi
+    left=$right
+    right=${!i}
+  done
+  eval unset $left
+}
+__tick_runtime_push() {
+  local value="${1/\'/\\\'}"
+  local base=$2
+  local lastarg=${!#}
+
+  let nextval=${lastarg/$base/}+1
+  nextval=`printf "%012d" $nextval`
+
+  eval $base$nextval=\'$value\'
+}
+
+tickParse() {
+  eval `echo "$1" | __tick_json_tokenize | __tick_json_parse | tr '\n' ';'`
+}
+## } End of Runtime
+
+
+[ $__tick_var_tokenized ] || __tick_fun_tokenize
