User Tools

Site Tools


ircterm

Project Background

Rob wanted a way to promote IRC use and make it feel more part of the lab rather than a separate 'IRC club', and also open it up to non-IRC users and provide a way to quickly reply. Similar IRC terminals exist at other hackerspaces, such as Helsinki Hacklab.

Main Hardware Components

  • Raspberry Pi A+ & 3D printed case
  • Some crappy 'PiHut' rt2800-based wifi dongle
  • Optiquest Q22wb (Viewsonic/BENQ) 22“ 1680×1050 (16:10) TFT mounted vertically, provided by shabble
  • Wall mount VESA arm
  • Also a passive USB 2.0 hub and a small USB keyboard

Piecing it together

The Pi is back-powered via the hub, which is in turn back-powered via a small in-line 5v 1A PSU originally for a Zip drive. There are a few of these useful PSUs in use in the lab. The back-powering is a result of only wanting to use bits in the 'cables for butchering' box.

Pi, USB hub, and PSU are velcro'd on to the back of the monitor. The monitor is mounted on the wall using a wall bracket salvaged from a smashed TV that was being thrown out. The wall bracket is capable of a wide range of movement.

The keyboard is bodged in place using lots of hot glue and some L brackets which are stuffed behind the conduit. Seems solid for now.

Wifi

Terminal is connected to the main 'Hacklab' network. Wifi was showing to be very unreliable in 'n' mode. Having forced an arbitrary speed of 22Mbit/s, the wifi is now stable. Other Pis using similar dongles have experienced high latency and loss too. The problem doesn't exist when connected to different access points.

The following script has been added:

/etc/network/if-up.d/iwconfig

#!bin/sh

iwconfig wlan0 rate 22 fixed

The following has also been observed from time to time in the logs (syslog, dmesg):

[37316.894424] ieee80211 phy0: rt2800usb_entry_txstatus_timeout: Warning - TX status timeout for entry 15 in queue 2
[37317.005566] ieee80211 phy0: rt2800usb_txdone: Warning - Got TX status for an empty queue 2, dropping

Automatically reconnecting wifi

/etc/rc.local:

/root/wifimonitor 2>&1 &

/root/wifimonitor:

#!/bin/bash

while true ; do
   if ifconfig wlan0 | grep -q "inet addr:" ; then
      sleep 60
   else
      ifdown wlan0
      sleep 10
      ifup --force wlan0
      sleep 10
   fi
done

OS Config

Stock Raspbian with all x11-* and various other things removed.

/etc/inittab modified to replace tty1 with IRC:

1:2345:once:/root/irssi
2:23:respawn:/sbin/getty 38400 tty2
3:23:respawn:/sbin/getty 38400 tty3
4:23:respawn:/sbin/getty 38400 tty4
5:23:respawn:/sbin/getty 38400 tty5
6:23:respawn:/sbin/getty 38400 tty6

/root/irssi:

#!bin/bash
screen -S IRC su - --command "irssi" -l pi

It's run a screen session to allow easy remote irssi maintaining via screen -x.

The console font has been changed using:

sudo dpkg-reconfigure console-setup

Terminus font in UTF8, at size 16×32.

Powering on/off the screen automatically

The screen turns off when the lab is empty and turns back on again as soon as someone enters the lab and triggers the PIR. This happens via the message bus and is handled by idle.py which is currently run from rc.local. idle.py was written by Tim initially.

/etc/rc.local:

/home/pi/idle.py > /dev/null 2>&1 &

/home/pi/idle.py:

#!/usr/bin/env python

import paho.mqtt.client as mqtt
import subprocess

last_state = None

def on_connect(client, userdata, flags, rc):
    client.subscribe("sensor/global/presence")

def on_message(client, userdata, msg):
    global last_state

    # ignore retained (non-realtime) messages
    #if msg.retain:
    #    return

    if last_state != msg.payload:
        # state has changed
        if msg.payload == "active":
            # screen on
            subprocess.call("tvservice -p", shell=True)
        elif msg.payload == "empty":
            # screen off
            subprocess.call("tvservice -o", shell=True)
        last_state = msg.payload

m = mqtt.Client()
m.on_connect = on_connect
m.on_message = on_message
m.connect("mqtt")
m.loop_forever()

Required to run:

apt-get install python-pip
pip install paho-mqtt

Log file of TV status (due to people wondering if it doesn't actually ever turn off):

~/idle.log

Irssi config

Summary:

  • Auto connect to freenode
  • NickServ identification
  • Main channel window with only PUBLICS, ACTIONS and NICKS.
  • Small split window at the top with everything else including server messages and channel join/parts and quits.
  • Highlight triggers ICQ 'uhoh' to be played.
servers = (
  {
    address = "irc.freenode.net";
    chatnet = "freenode";
    port = "6667";
    use_ssl = "no";
    ssl_verify = "no";
    autoconnect = "yes";
  }
);

chatnets = {
  freenode = {
    type = "IRC";
    autosendcmd = "/^msg nickserv identify <PASSWORD>;/^win 2";
  };
};

channels = (
  { name = "#irssi"; chatnet = "ircnet"; autojoin = "No"; },
  { name = "silc"; chatnet = "silc"; autojoin = "No"; },
  { name = "#edinhacklab"; chatnet = "freenode"; autojoin = "yes"; }
);

aliases = {
  J = "join";
  WJOIN = "join -window";
  WQUERY = "query -window";
  LEAVE = "part";
  BYE = "quit";
  EXIT = "quit";
  SIGNOFF = "quit";
  DESCRIBE = "action";
  DATE = "time";
  HOST = "userhost";
  LAST = "lastlog";
  SAY = "msg *";
  WI = "whois";
  WII = "whois $0 $0";
  WW = "whowas";
  W = "who";
  N = "names";
  M = "msg";
  T = "topic";
  C = "clear";
  CL = "clear";
  K = "kick";
  KB = "kickban";
  KN = "knockout";
  BANS = "ban";
  B = "ban";
  MUB = "unban *";
  UB = "unban";
  IG = "ignore";
  UNIG = "unignore";
  SB = "scrollback";
  UMODE = "mode $N";
  WC = "window close";
  WN = "window new hide";
  SV = "say Irssi $J ($V) - http://irssi.org/";
  GOTO = "sb goto";
  CHAT = "dcc chat";
  RUN = "SCRIPT LOAD";
  CALC = "exec - if command -v bc >/dev/null 2>&1\\; then printf '%s=' '$*'\\; echo '$*' | bc -l\\; else echo bc was not found\\; fi";
  SBAR = "STATUSBAR";
  INVITELIST = "mode $C +I";
  Q = "QUERY";
  "MANUAL-WINDOWS" = "set use_status_window off;set autocreate_windows off;set autocreate_query_level none;set autoclose_windows off;set reuse_unused_windows on;save";
  EXEMPTLIST = "mode $C +e";
  ATAG = "WINDOW SERVER";
  UNSET = "set -clear";
  RESET = "set -default";
};

statusbar = {
  # formats:
  # when using {templates}, the template is shown only if it's argument isn't
  # empty unless no argument is given. for example {sb} is printed always,
  # but {sb $T} is printed only if $T isn't empty.

  items = {
    # start/end text in statusbars
    barstart = "{sbstart}";
    barend = "{sbend}";

    topicbarstart = "{topicsbstart}";
    topicbarend = "{topicsbend}";

    # treated "normally", you could change the time/user name to whatever
    time = "{sb $Z}";
    user = "{sb {sbnickmode $cumode}$N{sbmode $usermode}{sbaway $A}}";

    # treated specially .. window is printed with non-empty windows,
    # window_empty is printed with empty windows
    window = "{sb $winref:$tag/$itemname{sbmode $M}}";
    window_empty = "{sb $winref{sbservertag $tag}}";
    prompt = "{prompt $[.15]itemname}";
    prompt_empty = "{prompt $winname}";
    topic = " $topic";
    topic_empty = " Irssi v$J - http://www.irssi.org";

    # all of these treated specially, they're only displayed when needed
    lag = "{sb Lag: $0-}";
    act = "{sb Act: $0-}";
    more = "-- more --";
  };

  # there's two type of statusbars. root statusbars are either at the top
  # of the screen or at the bottom of the screen. window statusbars are at
  # the top/bottom of each split window in screen.
  default = {
    # the "default statusbar" to be displayed at the bottom of the window.
    # contains all the normal items.
    window = {
      disabled = "no";

      # window, root
      type = "window";
      # top, bottom
      placement = "bottom";
      # number
      position = "1";
      # active, inactive, always
      visible = "active";

      # list of items in statusbar in the display order
      items = {
        barstart = { priority = "100"; };
        time = { };
        user = { };
        window = { };
        window_empty = { };
        lag = { priority = "-1"; };
        act = { priority = "10"; };
        more = { priority = "-1"; alignment = "right"; };
        barend = { priority = "100"; alignment = "right"; };
      };
    };

    # statusbar to use in inactive split windows
    window_inact = {
      type = "window";
      placement = "bottom";
      position = "1";
      visible = "inactive";
      items = {
        barstart = { priority = "100"; };
        window = { };
        window_empty = { };
        more = { priority = "-1"; alignment = "right"; };
        barend = { priority = "100"; alignment = "right"; };
      };
    };

    # we treat input line as yet another statusbar :) It's possible to
    # add other items before or after the input line item.
    prompt = {
      type = "root";
      placement = "bottom";
      # we want to be at the bottom always
      position = "100";
      visible = "always";
      items = {
        prompt = { priority = "-1"; };
        prompt_empty = { priority = "-1"; };
        # treated specially, this is the real input line.
        input = { priority = "10"; };
      };
    };

    # topicbar
    topic = {
      type = "root";
      placement = "top";
      position = "1";
      visible = "always";
      items = {
        topicbarstart = { priority = "100"; };
        topic = { };
        topic_empty = { };
        topicbarend = { priority = "100"; alignment = "right"; };
      };
    };
  };
};
settings = {
  core = {
    real_name = "Edinburgh Hacklab";
    user_name = "ircpi";
    nick = "hacklab-";
  };
  "fe-text" = { actlist_sort = "refnum"; };
  "fe-common/core" = {
    window_check_level_first = "yes";
    window_default_level = "-ALL PUBLIC ACTIONS NICKS";
    beep_when_window_active = "yes";
    beep_when_away = "yes";
    beep_msg_level = "HILIGHT";
    bell_beeps = "yes";
  };
  "perl/core/scripts" = {
    beep_cmd = "/srv/hacksense/bin/request-soundfile uhoh.mp3 &";
  };
};
hilights = ( { text = "hacklab-"; nick = "yes"; word = "yes"; } );
windows = {
  1 = {
    immortal = "yes";
    name = "(status)";
    level = "CRAP MSGS NOTICES SNOTES CTCPS JOINS PARTS QUITS KICKS MODES TOPICS WALLOPS INVITES DCC DCCMSGS CLIENTNOTICES CLIENTCRAP CLIENTERRORS HILIGHTS";
    sticky = "yes";
  };
  2 = {
    level = "PUBLICS ACTIONS NICKS";
    items = (
      {
        type = "CHANNEL";
        chat_type = "IRC";
        name = "#edinhacklab";
        tag = "freenode";
      }
    );
  };
};
mainwindows = {
  2 = { first_line = "8"; lines = "43"; };
  1 = { first_line = "1"; lines = "7"; };
};

There are two plugins in use. nickcolor.pl and beep_beep.pl. Both are unmodified.

Playing the sound

Part of the 'hacksense' stuff has been copied over:

  • /srv/hacksense/bin/request-soundfile
  • uhoh.mp3 is on doorbot which has the speaker attached to it.

In irssi config: beep_cmd = ”/srv/hacksense/bin/request-soundfile uhoh.mp3 &“

ircterm.txt · Last modified: 2016-10-07 17:04 by tim