#! /usr/bin/env python
# 
# L. Le Guillou
# Script to turn on/off & know the status of the Raritan outlets
# and display current status.
#
# Originally written for Skydice (@Skymapper, Siding Spring)
# 
# 2017-11-02: Version for the DICE source elements at the T152 (OHP) 
# 2018-03-08: Version for the DICE telescope elements at Jumeles
#

import sys
import os, os.path
import subprocess
import time

HOST = 'raritan' # Raritan, connected through eth1 (pointopoint)
# COMMUNITY = "raritan_public"
COMMUNITY = "raritan_private"
SNMPGET = "snmpget"
SNMPSET = "snmpset"
SNMP_OPTIONS = ["-v2c", "-Ovq", "-c", COMMUNITY]
PORT = 161
OID_PREFIX = "1.3.6.1.4.1.13742.4.1.2.2.1.3"

outlets = {
    #------------------------------------------------    
    "LASER":              1,
    #------------------------------------------------    
    "PC104":              2,
    "PC-104":             2, # name variant
    #------------------------------------------------    
    "SBIG":               3,
    #------------------------------------------------    
    "PULSAR":             4,
    "PULSAR2":            4, # name variant
    #------------------------------------------------    
    "PEGASUS":            5,
    "PEGASUS2":           5, # name variant
    #------------------------------------------------    
    "OUTLET 6":           6,
    "OUTLET 7":           7,
    "OUTLET 8":           8    }


# back dictionary 
outlets_names = {}
for k, v in outlets.iteritems():
    outlets_names[v] = str(k)

# print outlets_names
    
def get_status(outlet):
    oid = OID_PREFIX + "." + str(outlet)
    cmd = [SNMPGET] + SNMP_OPTIONS + [HOST  + ":" + str(PORT)] + [oid]
    cmd = " ".join(cmd)
    # print cmd
    output = subprocess.Popen(cmd, stdout = subprocess.PIPE, shell=True).communicate()[0]
    # print output
    return bool(int(output))
    # os.system(cmd)

def set_status(outlet, on):
    oid = OID_PREFIX + "." + str(outlet)
    cmd = [SNMPSET] + SNMP_OPTIONS + [HOST  + ":" + str(PORT)] + \
        [oid] + ["i"] + [str(int(on))]
    cmd = " ".join(cmd)
    # print cmd
    output = subprocess.Popen(cmd, stdout = subprocess.PIPE, shell=True).communicate()[0]
    # print output
    return bool(int(output))
    # os.system(cmd)


def display(outlet):
    result = get_status(outlet)
    print "RPC " + HOST + ": " + outlet,  "[" + outlets_names[int(outlet)] + "]",
    if result:
        print "ON"
    else:
        print "OFF"


def usage():
    print >>sys.stderr, \
        """
usage: dicepower <outlet> [ON|OFF]

    <outlet> may be:
      A number [1-8]
      A name in the following device list: 
         laser
         PC104
         SBIG
         PULSAR2
         Pegasus2
      Or the 'all' value.

    Without ON/OFF specified, the current outlet status
    will be displayed.

    Examples:

    dice@diceacq:~$ dicepower all
    RPC raritan: 1 [LASER] OFF
    RPC raritan: 2 [PC104] OFF
    RPC raritan: 3 [SBIG] OFF
    RPC raritan: 4 [PULSAR2] OFF
    RPC raritan: 5 [PEGASUS] OFF
    RPC raritan: 6 [OUTLET 6] OFF
    RPC raritan: 7 [OUTLET 7] OFF
    RPC raritan: 8 [OUTLET 8] OFF

    dice@diceacq:~$ dicepower laser
    RPC raritan: 1 [LASER] OFF

    dice@diceacq:~$ dicepower laser on
    RPC raritan: 1 [LASER] OFF
    RPC raritan: 1 [LASER] ON

    dice@diceacq:~$ dicepower laser 
    RPC raritan: 1 [LASER] ON

    dice@diceacq:~$ dicepower laser off
    RPC raritan: 1 [LASER] ON
    RPC raritan: 1 [LASER] OFF

"""

outlet = None
on = None  # True / False

# print sys.argv

if len(sys.argv) < 2:
    usage()
    sys.exit(1)

# host   = sys.argv[1]
outlet = sys.argv[1].upper()

if outlet not in ["1","2","3","4","5","6","7","8"]:
    if outlet in outlets.keys():
        outlets_to_look = [str(outlets[outlet])]

    elif outlet in ["ALL", 'all']:
        outlets_to_look = ["1","2","3","4","5","6","7","8"]

    else:
        print >>sys.stderr, "error: Unknown outlet on this device"
        sys.exit(2)
else:
    outlets_to_look = [outlet]
    


if len(sys.argv) == 3:
    on_arg = sys.argv[2]
    on_arg = on_arg.upper()
    if (on_arg == "ON") or (on_arg == "1"):
        on = True
    elif (on_arg == "OFF") or (on_arg == "0"):
        on = False
    else:
        usage()
        sys.exit(1)


for outl in outlets_to_look:
    display(outl) # If no ON/OFF, just display the state

if on in [True, False]:
    for outl in outlets_to_look:
        result = set_status(outl, on)
        time.sleep(0.5)
        display(outl)

# snmpget -v2c -c raritan_public dicehead-rpc:161 1.3.6.1.4.1.13742.4.1.2.2.1.2.4
# SNMPv2-SMI::enterprises.13742.4.1.2.2.1.2.4 = label outlet 4


# snmpget -v2c -c raritan_public dicehead-rpc:161 1.3.6.1.4.1.13742.4.1.2.2.1.3.5

# snmpset -v2c -c raritan_public dicehead-rpc:161 1.3.6.1.4.1.13742.4.1.2.2.1.3.5 i 1

# snmpset -v2c -c raritan_public dicehead-rpc:161 1.3.6.1.4.1.13742.4.1.2.2.1.3.5 i 0



