Jag har nu kollat på detta i detalj och kommit fram till följande.
Pingchecker har ett användningsområde, till ex för att hålla reda på om en dator är på eller av. Men att försöka använda detta plugin för att försöka hålla reda på om en mobil befinner sig på nätverket eller inte och sen styra scenarion utifrån detta är helt meningslöst.
Anledningen är att telefoner försvinner långa perioder från närverket för att spara ström. En iPhone är väldigt sofestikerad och kan försvinna så länge som 18-20 minuter helt från nätet om man inte rör mobilen. Att hålla reda på en android-mobil är lättare.
Jag har skrivit en betydligt mer advancerad kodsnutt som addresserar detta problem, och som dessutom kan väcka upp mobiler om dom somnat. Jag har fått detta att fungera hyffsatt bra, koden är bra på att upptäcka när mobiler kommer hem. Men det tar lång tid innan man kan upptäcka att nån försvinnit. Koden nedan använder whatsapp för att rycka liv i mobiler som är borta samt att informera mobiler om att dom reggats på nätverket eller försvunnit.
Personligen tycker jag man bör använda geo-location istället. För oss som har IPhone så går det att få till detta med IFTTT , antingen via email eller gtalk eller dropbox och sedan styra enheter i SK utifrån detta, kanske att man kan göra detta med SMTP-pluginet till SK tillsammans med IFTTT utan att skriva en enda kodrad själv. Jag återkommer när jag fått till det, men är säker på att det går.
Jag bifogar en ganska advancerad pingchecker i python för dom som ändå är intresserade, om man inte kan python så tror jag inte att man kommer kunna få igång den.
Jag kommer troligen fortsätta använda den, eftersom:
* Den kommer att fungera vid strömavbrott bara man håller SK-servern vid liv ( jag kör en laptop bara )
* Den kommer att fungera när internet är nere
* Jag kan confa upp mormors och barnvaktens mobiler i systemet utan en massa tjafs
* Den funkar även på äldre telefoner som inte kör android eller iOS.
vissa saker ovan är viktiga för mig då jag hade tänkt bygga "larm" i ett senare skede, typ dra igång sirener om ingen är hemma samt att rörelse-detektorer kommer igång.
Code: Select all
#!/usr/bin/python
import datetime
import time
import subprocess
import sys
import os
import logging
logging.getLogger("Yowsup.runtime").setLevel(logging.ERROR)
import Yowsup
from Yowsup.connectionmanager import YowsupConnectionManager
import argparse, sys, os, csv
from Yowsup.Common.utilities import Utilities
from Yowsup.Common.debugger import Debugger
from Yowsup.Common.constants import Constants
from Examples.CmdClient import WhatsappCmdClient
from Examples.EchoClient import WhatsappEchoClient
from Examples.ListenerClient import WhatsappListenerClient
from Yowsup.Registration.v2.existsrequest import WAExistsRequest as WAExistsRequestV2
from Yowsup.Registration.v2.coderequest import WACodeRequest as WACodeRequestV2
from Yowsup.Registration.v2.regrequest import WARegRequest as WARegRequestV2
from Yowsup.Contacts.contacts import WAContactsSyncRequest
import threading,time, base64
from collections import namedtuple
def init_logging():
import logging
# set up logging to file - see previous section for more details
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
datefmt='%m-%d %H:%M',
filename='hal.log' )
# define a Handler which writes INFO messages or higher to the sys.stderr
console = logging.StreamHandler()
console.setLevel(logging.WARNING)
# set a format which is simpler for console use
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
# tell the handler to use this format
console.setFormatter(formatter)
# add the handler to the root logger
logging.getLogger('').addHandler(console)
# Now, we can log to the root logger, or any other logger. First the root...
logging.error('HAL started')
init_logging()
phone_info = {}
Phone = namedtuple('Phone', ['ip','number', 'last_seen', 'last_updated_up', 'last_updated_down', 'marked_as' ])
mark_phone_down_after = 1200
wake_up_phone_after = 1140
ping_phone_every = 30
update_sk_every = 60
now = datetime.datetime.now() - datetime.timedelta(0,ping_phone_every)
# initial data
phone_info["person1"] = {
'ip' : "10.0.0.107",
'number' : "4670333333",
'last_seen' : now,
'last_updated_up' : now,
'last_updated_down' : now,
'marked_as' : None,
'notified_lost_unit' : False,
'pinged_lost_unit' : True,
'sk_unit' : 25
}
phone_info["person2"] = {
'ip' : "10.0.0.114",
'number' : "467344444",
'last_seen' : now,
'last_updated_up' : now,
'last_updated_down' : now,
'marked_as' : None,
'notified_lost_unit' : False,
'pinged_lost_unit' : True,
'sk_unit' : 45
}
def ping_phone(phone):
ip = phone_info[phone]['ip']
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import IP,sr1,conf,ICMP
TIMEOUT = 1
conf.verb = 0
found_at_least_one_phone = False
packet = IP(dst=ip, ttl=0)/ICMP()
reply = sr1(packet, timeout=TIMEOUT)
if not (reply is None):
#print reply.src, "is online"
#print phone_info[ip]
phone_info[phone]['last_seen'] = datetime.datetime.now()
phone_info[phone]['notified_lost_unit'] = False
phone_info[phone]['pinged_lost_unit'] = False
found_at_least_one_phone = True
evaluate_phone_online(phone)
logging.info("ICMP reply recieved from %s" % packet[IP].dst)
else:
evaluate_phone_offline(phone)
logging.info("Timeout waiting for %s" % packet[IP].dst)
return found_at_least_one_phone
def update_all_phones():
for phone in phone_info :
last = datetime.datetime.now() - phone_info[phone]['last_seen']
if last.seconds > ping_phone_every:
logging.info("Pining phone: %s" %phone)
ping_phone(phone)
for phone in phone_info:
diff = datetime.datetime.now() - phone_info[phone]['last_seen']
logging.debug ( phone + ": " + str(diff.seconds) + " " + str( phone_info[phone]['last_seen'] ))
def evaluate_phone_offline(phone):
# if (datetime.datetime.now() - phone_info[phone]['last_updated_up']).seconds > wake_up_phone_after:
# wake_up_phone(phone)
if (datetime.datetime.now() - phone_info[phone]['last_updated_up']).seconds > mark_phone_down_after:
mark_offline_in_sk(phone)
if phone_info[phone]['marked_as'] == 'UP':
send_whatsapp_messgage(phone,"Good bye!")
logging.warning( "Sent goodbye to phone: " + phone)
phone_info[phone]['notified_lost_unit'] = True
phone_info[phone]['marked_as'] = 'DOWN'
logging.warning( "Marked phone as DOWN: " + phone)
def evaluate_phone_online(phone):
if phone_info[phone]['marked_as'] == 'DOWN':
logging.warning( "Sent welcome to phone: " + phone)
send_whatsapp_messgage(phone,"Welcome Home!")
phone_info[phone]['notified_lost_unit'] = False
if phone_info[phone]['marked_as'] != 'UP':
logging.warning( "Marked phone as UP: " + phone)
phone_info[phone]['marked_as'] = 'UP'
mark_online_in_sk(phone)
def mark_online_in_sk(phone):
if (datetime.datetime.now() - phone_info[phone]['last_updated_up']).seconds > update_sk_every:
import requests
logging.info( "Updating SK Online: "+phone)
url = 'http://user:pass@10.0.0.113:8800/datasources/'+str(phone_info[phone]['sk_unit'])+'/addvalue?value=1'
response = requests.get(url)
phone_info[phone]['last_updated_up'] = datetime.datetime.now()
def mark_offline_in_sk(phone):
if (datetime.datetime.now() - phone_info[phone]['last_updated_down']).seconds > update_sk_every:
import requests
logging.info( "Updating SK Offline:" + phone)
url = 'http://user:pass@10.0.0.113:8800/datasources/'+str(phone_info[phone]['sk_unit'])+'/addvalue?value=0'
response = requests.get(url)
phone_info[phone]['last_updated_down'] = datetime.datetime.now()
def send_whatsapp_messgage(phone,m):
Debugger.enabled = False
y = YowsupConnectionManager()
methodsInterface = y.getMethodsInterface()
p = "xxxxxxxxxxxxxxxx+ZAeFXPw="
password = base64.b64decode(bytes(p.encode('utf-8')))
methodsInterface.call("auth_login", ("46739000000", password))
methodsInterface.call("message_send", (phone_info[phone]['number']+ "@s.whatsapp.net", m))
def wake_up_phone(phone):
if phone_info[phone]['marked_as'] == 'DOWN':
return
else:
if phone_info[phone]['pinged_lost_unit'] == False:
logging.warning ( "Trying to wake up phone: " + phone )
send_whatsapp_messgage(phone ,"ping?")
phone_info[phone]['pinged_lost_unit'] = True
# Wait for message to arrive
time.sleep(5)
while True:
update_all_phones()
time.sleep(3)