arp-20180622.py (Código fuente)

#!/usr/bin/env python3

# (c) 2018 Jesús Cea Avión - jcea@jcea.es - https://www.jcea.es/
# This code is licensed under AGPLv3.

import time
import subprocess
import socket

import telegram.ext


MAC = 'XX:XX:XX:XX:XX:XX'

# Esperamos a tener red porque no queremos que se pierda la
# primera notificación de arranque.
# Además, no queremos un falso negativo cuando aún no tenemos red.
while True:
    try:
        socket.gethostbyname('api.telegram.org')
        break
    except socket.gaierror:
        time.sleep(1)

TELEGRAM_TOKEN = '0000:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'

updater = telegram.ext.updater.Updater(TELEGRAM_TOKEN)
updater.start_polling(timeout=60)
job_queue = updater.job_queue


presencia = None
prefix = ' <b>Arranque del sistema:</b>'

current_message = ''

# Usuarios autorizados
# jcea y L*****
usuarios = (00000000, 00000000)


def callback(bot, update):
    usuario = update.effective_user['id']
    if usuario in usuarios:
        bot.send_message(usuario, text=current_message, parse_mode='HTML')


updater.dispatcher.add_handler(
        telegram.ext.MessageHandler(
            filters=(telegram.ext.filters.Filters.user(user_id=usuarios) &
                     telegram.ext.filters.Filters.text),
            callback=callback,
            ))


def msg(bot, job):
    texto = job.context['msg']
    for i in usuarios:
        bot.send_message(i, text=texto, parse_mode='HTML')


while True:
    r = subprocess.run(
            [('for i in `/usr/bin/seq 1 254`; '
              'do /bin/ping -c 1 192.168.1.$i & done; wait')],
            stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
            shell=True, timeout=60, check=True)
    r = subprocess.run(
            ['/usr/sbin/arp', '-n'],
            universal_newlines=True,
            stdout=subprocess.PIPE, stderr=subprocess.DEVNULL,
            timeout=60, check=True)
    presente = r.stdout.find(MAC) != -1
    if presencia != presente:
        if presente:
            current_message = ('%s:%s La luz está encendida'
                               % (time.ctime(), prefix))
        else:
            current_message = ('%s:%s La luz <b>ESTÁ APAGADA</b>'
                               % (time.ctime(), prefix))
        print(current_message)

        job_queue.run_once(msg, when=0, context={'msg': current_message})

        presencia = presente
        prefix = ''
    time.sleep(60)