User Tools

Site Tools


spacefoo:beamer

Beamer

To be able to send commands to the Beamer (Acer <insertNumberHere>), we need to connect via RS232. a single Cable was too short, so we had to make our own, using an adapter to send the signal over a self patched RJ45 cable.

Execution

Will be hosted and connected to Fnord23.

  • adduser beamer
  • set /etc/shadow passwd to ! (do not allow login/shell)
  • adduser beamer dialout
  • create beamer:www-data script, set u+s and g+x (Does not work because its a shell script)
  • add into /etc/nginx/sitex-enabled/<page>
  • go to <fnord>/beamer and select what you want ;)

Nginx-Config

location /beamer {

  content_by_lua '
    ngx.req.read_body()
    local args = ngx.req.get_uri_args()
    local prog = "/home/beamer/scripts/beamer.sh"
    
    local a_id = args.id
    local a_json = args.json
    
    local json = 1
    local contType = "application/json"
    local id = nil
 
    if a_json == nil then
      json = 0
      contType = "text/html"
    end

    if a_id ~= nil then
      id = tonumber(a_id)
    end

    ngx.header.content_type = contType
    prog = prog .. " " .. json
    if id ~= nil then
      prog = prog .. " " .. id
    end

    local data=io.popen(prog)
    ngx.say(data:read("*a"))
    data:close()
  ';
}

TODO:

  • allow parameters to be spacy “<long param>”
  • use “key:param” style

Script

#!/bin/bash
#
# Beamer API stuff
#
# beamer.sh <json 0|1> (<id>)
#
# gives html|json reply of all id's
# Sends given ID's command over ttyUSB
#
# @author mauli
# @contact mauli@darkfasel.net
# @license WTFPL
# @organization maulware
#
######################################################
#            Global Variables
#####################################################

scriptFolder="/home/beamer/scripts"
lock="/tmp/beamerExec.lock"
json=0
declare -A ret=(["msg"]="", ["err"]="", ["status"]="")
j_error=()
j_info=()

######################################################
cd "$scriptFolder"

###############################################################
####################### Internal Functions ####################

#
#print_data_json_array <name> <array>
#
i_print_json_data()
{

  grep -v "^#" ./*.dat \
    | awk 'NR%4==1||NR%4==0 { print $0 }' \
    | sed ':a;N;$!ba;s/\n / /g' \
    | sed -E "s/(^[0-9]+) /\1,/" \
    | awk -F, 'NR>0{arr[$0]++}END{for (a in arr) print "\""a"\"", "\""arr[a]"\""}' \
    | sed -E "s/^/{/; $ ! s/ \"1\"$/},/; s/ \"1\"$/}]/" \
    | sed -E "s/^\{\"\"\},/\"data\"\:[/" \
    | sed -E "s/(\"[0-9]+),/\1\":\"/" \
    | sed -E "s/\{(\"[0-9]+\"):(\"[^\"]+\")\}/\{\"id:\":\1,\"name\":\2\}/"

}

i_print_html_data()
{
  echo "<hr>"
  grep -v "^#" ./*.dat | sed -E 's/^([0-9]+$)/<a href=?id=\1/' \
        | sed -E 's/^ (\*.*$)//' \
        | sed -E 's/ (([0-9A-F]{2}|,){10,})/\&hex=\1>/' \
        | sed -E 's/(<a href)/ <\/a><br>\r\n\1/' \
        | sed ':a;N;$!ba;s/\n//g' \
        | sed '0,/<\/a><br>/s///'
}

i_print_error_web()
{
  for err in "${!j_error[@]}";do
    echo "<p class='error'>${j_error[$err]}</p>"
  done
}
i_print_info_web()
{
  for inf in "${!j_info[@]}";do
    echo "<p class='info'>${j_info[$inf]}</p>"
  done
}

i_print_error_json()
{
  echo "\"error\":["
  echo -n `for err in "${j_error[@]}"; do
    echo "{\"err\":\"$err\"},"
  done` | sed "s/,$//"
  echo "],"
}
i_print_info_json()
{
  echo "\"info\":["
  echo -n `for inf in "${j_info[@]}"; do
    echo "{\"info\":\"$inf\"},"
  done` | sed "s/,$//"
  echo "],"
}

#######################################################################
########################## Direct Functions ###########################

i_start_json()
{
  if [[ $json != 0 ]];then
    echo "{"
  fi
}

i_end_json()
{
  if [[ $json != 0 ]];then
    #added for not having to do complicated stuff to remove tailing ,
    echo "{\"status\":\"OK\"}"
    echo "}"
  fi
}

i_start_web()
{

  cat << EOF
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Beamer Web</title>
<style type="text/css">

.error, .info{
  padding: 0.5em;
}

.error {
  background-color: #CCCCCC;
  color: red;
}
.info{
  background-color: #10AC93;
  color: white;
}
</style>
</head>
<body>
EOF
}

i_end_web()
{
  cat <<EOF
</body>
</html>
EOF
}

#######################################################################

start()
{
  if [[ "$json" == "0" ]]; then
    i_start_web
  else
    i_start_json
  fi
}
end()
{
  if [[ "$json" == "0" ]]; then
    i_end_web
  else
    i_end_json
  fi
}

print_stati()
{
  if [[ "$json" == "0" ]]; then
    i_print_error_web
    i_print_info_web
  else
    i_print_error_json
    i_print_info_json
  fi
}

info()
{
  j_info+=("$1")
}

print_info()
{
  ##todo: use print_error code but for both!
  echo "info: $1"
}

error()
{
  j_error+=("$@")
}


#execute_func <id>
execute_func()
{
  local id=$1
  local command=""
  command=`grep -v "^#" ./*.dat | grep -B0 -A1 -e "^$id$" | tail -n 1`
  command=$(sed 's/^ //' <<< $command)

  if ! [[ -a "$lock" ]]; then
    touch "$lock"
    #stty -F /dev/ttyUSB0 9600
    echo -ne "$command" > /dev/ttyUSB0;
    sleep 0.5;
    rm "$lock"
  else
    error "PLEASE, do not flood the connection"
  fi

#  read LINE < /dev/ttyUSB0;
#  ret["ret"]="$LINE";
}

# print_data <json 0|1>
print_data()
{

#TODO add error if *.dat not avaiable

  if [[ "$json" == "0" ]]; then
    i_print_html_data
  else
    i_print_json_data
  fi

}


####################################################################
######################### LOGIC ####################################

if [ "$#" -ge 1 ];then
  json=$1
  p_json='^[0-1]$'
  if ! [[ "$json" =~ $p_json ]] ; then
    #disable json if invalid
    json=0
  fi
fi

#####################################################################
########################### SECURITY ################################

disable=1

if [[ "$disable" == 1 ]];then
  error "
  Disabled until space is ~UP.
  ask at irc.darkfasel.net  #chaossbg
  if you want further information.
  "

  ### removing all variables
  while (( "$#" )); do
    shift
  done
fi

########################### Program #################################

start

if [ "$#" -ge 2 ];then

  id="$2"
  re='^[0-9]+$'

  #Execute if not blacklisted
  if [[ $id =~ $re ]] ; then
    #BLACLISTED: OKOKOKOK\r Power on
    if [ "$id" == "1" ];then
      error "Function currently disabled"
    else
      execute_func $id
    fi
  else
    #No id or not an integer
    print_data
  fi
fi

print_stati

if [[ $json == 0 ]]; then
  echo "<hr><a href=/beamer>go back</a>"
  print_data
  echo "</html>"
fi

end


#@see https://gist.github.com/robspassky/1959319

#stty -F /dev/ttyUSB0 9600
#read LINE < /dev/ttyUSB0; echo $LINE

exit 0

TODO:

  • add REST API error / info messages
  • Add errors (missing dialout group for www-data, missing dat file)

Dat-File

RS232 Control codes

Connection description

working.

D'Sub 9

Due to this cable being too short, we need to patch our own that has the following patching:

14
23
32
41
46
55
64
78
87

(we ignore the 4↔6 connection)

D'Sub 9 to RJ45

Pins of Adapter are:

D'Sub RJ45
12
23
36
44
55
62
78
81
_____________ 
\ 5 4 3 2 1 / 
 \ 9 8 7 6 / 

Self patched RJ45 Cable

Due to what is needed, the pins are connected like this:

18
24
36
42
55
63
77
81
________/ \________         ________/ \________
| 1 2 3 4 5 6 7 8 |         | 8 4 6 2 5 3 7 1 |

Final overall pin connection

D'Sub9 RJ45 RJ45 D'Sub9
1244
2363
3632
4421
5555
6244
7818
8187
spacefoo/beamer.txt · Last modified: 2016/05/10 10:00 by mauli