Exemple #1
0
def command(message):
	msgList = message.split('_')
	if(msgList[0] == "wifiplug"):
		try:
			if('add' in msgList[1]):
				addNewPlug(int(msgList[2])) 
				return	

			id = int(msgList[1]) - 1
			print ips[id]
			if(msgList[2] == "on"):
				plug = SmartPlug(ips[id])
				print("Current state: %s" % plug.state)
				plug.state = "ON"
				return

			if(msgList[2] == "off"):
				plug = SmartPlug(ips[id])
				print("Current state: %s" % plug.state)
				plug.state = "OFF"
				return

		except ValueError:
			logging.warning('Invalid command: Incorrect id format')
			return
		except Exception as e:
			logging.warning(e)
			return
Exemple #2
0
 def action(self, action, timeout=None):
     action = action.upper()
     try:
         settings.plugins.lights[self.room]
     except Exception:
         return
     try:
         self.isOpen(9999)
     except Exception:
         return
     if not self.post.ack():
         return
     type = settings.plugins.lights[self.room]['type']
     if type == 'plug':
         emoji = ':electric_plug:'
         tplinklight = SmartPlug(
             settings.plugins.lights[self.room]['ipaddr'])
     else:
         type = 'light'
         emoji = ':bulb:'
         tplinklight = SmartBulb(
             settings.plugins.lights[self.room]['ipaddr'])
     if eval(os.environ['DEBUG']):
         debug = "[{}] ".format(device_name)
     else:
         debug = ""
     room_name = self.room.capitalize()
     if room_name.endswith('s'):
         room_name = room_name[:-1] + "'" + room_name[-1:]
     chat.post("{} {}Switching {} {} {}.".format(emoji, debug, room_name,
                                                 type, action.lower()))
     tplinklight.state = action
     if timeout is not None:
         sleep(float(timeout) * 60)
         tplinklight.state = 'OFF'
     self.post.unack()
Exemple #3
0
 def toggle(self):
     try:
         settings.plugins.lights[self.room]
     except Exception:
         return
     try:
         self.isOpen(9999)
     except Exception:
         return
     if not self.post.ack():
         return
     type = settings.plugins.lights[self.room]['type']
     if type == 'plug':
         emoji = ':electric_plug:'
         tplinklight = SmartPlug(
             settings.plugins.lights[self.room]['ipaddr'])
     else:
         emoji = ':bulb:'
         type = 'light'
         tplinklight = SmartBulb(
             settings.plugins.lights[self.room]['ipaddr'])
     if eval(os.environ['DEBUG']):
         debug = "[{}] ".format(device_name)
     else:
         debug = ""
     if tplinklight.state == "OFF":
         action = "ON"
     else:
         action = "OFF"
     room_name = self.room.capitalize()
     if room_name.endswith('s'):
         room_name = room_name[:-1] + "'" + room_name[-1:]
     chat.post("{} {}Switching {} {} {}.".format(emoji, debug, room_name,
                                                 type, action.lower()))
     tplinklight.state = action
     self.post.unack()
def live_check():

    # Please enter the IP of the tplink switches and the host associated to it.
    # example 'miner 01':{'switch':'192.168.1.10','host':'192.168.1.11'
    # The "xx" needs to be removed and replaced with the IP of your devices. If you have less/more
    #  devices, then add or remove to this dataframe as needed, each must be seperated with a comma
    #  and the end must have "}}"
    device = {'miner 01':{'switch':'192.168.1.xx','host':'192.168.1.xx'},
              'miner 02':{'switch':'192.168.1.xx', 'host':'192.168.1.xx'},
              'miner 03':{'switch':'192.168.1.xx', 'host':'192.168.1.xx'},
              'miner 04': {'switch': '192.168.1.xx', 'host': '192.168.1.xx'}}

    for each in device:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        #print ()
        miners = device[each]
        #print (miners['switch'])
        smartplug = SmartPlug(str(miners['switch']))
        print(smartplug.alias + " -- Host IP: "+ miners['host'] + " -- Smart Plug IP: " + miners['switch'] + " : ")
        print ('Testing SSH on ...' + miners['host'])

        # Change 22 to 3389 for windows, although that is not tested in this script, it should work by theory.
        results = s.connect_ex((miners['host'], 22))

        #print (results)

        if results == 0:
            print ("Port 22 reachable\n")
            #smartplug = SmartPlug(each)
            #print(smartplug.alias)
            #notifemail(str(smartplug.alias))

        else:

            # So the reason this is setup to make the call 3 times is due to how the protocol of a tplink device works.
            # These devices use udp to communicate so only calling ity once can cause the script to fail in it's action

            # also note that this takes advantage of a security flaw in the tplink design. These calls are happening
            # unathenticated, meaning anyone on your network can do this to your devices.

            print("SSH Closed")
            smartplug.state = "OFF"
            time.sleep(1)
            smartplug.state = "OFF"
            time.sleep(1)
            smartplug.state = "OFF"
            time.sleep(10)
            print (smartplug.state)
            smartplug.state = "ON"
            smartplug.state = "ON"
            time.sleep(1)
            smartplug.state = "ON"
            time.sleep(10)
            print(smartplug.state)
            print (smartplug.alias + " NEEDED TO BE RESTARTED\n")

            # sends the email, comment out if you don't want that functionality
            notifemail(str(smartplug.alias))

            #script sleeps for a bit
            time.sleep(30)



        s.close()
 def tpTogglePlug(self, ip):
     plug = SmartPlug(ip)
     if plug.state == 'OFF':
         plug.state = 'ON'
     else:
         plug.state = 'OFF'
Exemple #6
0
def main():

    import schedule
    from schedule import schedule

# Input variables

# Determine which rooms are rotated (only allowed to be on one at a time)

    rotate_plugnames = ['OBED', 'LBED']

#  Temperature settings.  Setback is change in setting temp for Ohmhour DR event.  Must be a negative number.

    deadband = 0.2
    setback = -3.0

# Get authorizations

    auth_dict = creds()

# Fresh tokens on program start

    ecobee_token_response = ecobee_tokens(True, datetime.datetime.min)

    auth = ecobee_token_response[0]
    last_refresh_time = ecobee_token_response[1]

#  Set up Ohmconnect call

    http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED', ca_certs=certifi.where())

    oc = [False]

# initial timestamp

    timestamp = '{:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now())

# Initial ecobee API call to populate room class
# TODO - refactor Ecobee API call and error handling (make consistent) as function
# TODO - Use /thermostatSummary URL to get Runtime Revision and refresh only when this changes

    try:

        thermostat_url = 'https://api.ecobee.com/1/thermostat?'
        payload = {'json': '{"selection":{"selectionType":"registered","includeSensors":"true"}}'}
        header = {'Content-Type': 'application/json;charset=UTF-8', 'Authorization': auth}

        response = requests.get(thermostat_url, headers=header, params=payload)

    except TimeoutError:

        err_string = (str(timestamp) + ' Timeout error in ecobee data call') + "\r"

        print(err_string)
        send_twilio_msg(err_string)

        log = open('log.txt', 'a+')
        log.write(err_string)
        log.close()

    data = response.json()

# Discover all temperature sensors

    tempdict = get_sensors(data)
    sensornames = list(tempdict.keys())

    if len(tempdict) == 0:

        print(data)
        sys.exit("no temperature sensors detected")

    else:

        pass

# Discover all plugs TODO consolidate into getplugs so it returns a dictionary of valid plug objects

    plugip = {}
    plugnames = []

    named_flag = False

    discover = get_plugs(plugip, plugnames, named_flag)

    plugip = discover[0]

    plugnames = discover[1]

    named_flag = True

    plugdict = {}

    for name in plugip:

        try:

            plugdict[name] = SmartPlug(plugip[name])

        except:

            pass

# Create list of valid rooms with both active sensors and plugs

    namelist = set(sensornames).intersection(plugnames)

# Define Room class

    class Room:

        def __init__(self, name, temp, status, temp_high, temp_low):
            self.name = name
            self.temp = temp
            self.status = status
            self.temp_high = temp_high
            self.temp_low = temp_low

# Initialize schedule and temperatures

    setdict = setpoints(timestamp)

# Define rooms and room dictionary

    roomdict = {}

    for name in namelist:

        roomdict[name] = Room(name, tempdict[name], 'OFF', setdict[name]+deadband, setdict[name])

# Initialize error counter & loop status

    sensor_error_count = 0

    last_loop_sched = True

    start_turn = 0

# Get last schedule modification time

    mtime = os.path.getmtime('schedule.py')

# Start main loop

    while True:

# Automatically reload schedule to capture changes

        mtime_now = os.path.getmtime('schedule.py')

        if mtime_now != mtime:

            importlib.reload(sys.modules['schedule'])
            from schedule import schedule
            print("Schedule Updated")

        else:

            pass

        mtime = mtime_now

# Token refresh

        ecobee_token_response = ecobee_tokens(False, last_refresh_time)

        last_refresh_time = ecobee_token_response[1]

# time handling

        timestamp = '{:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now())

# Determine Schedule or Sleep mode

        setdict = setpoints(timestamp)

        setvals = []

        for name in namelist:

            setvals.append(setdict[name])

        if len(setvals) == setvals.count(-999):

            sched = False

        else:

            sched = True

# Schedule (active) mode

        if sched is True:

            # Token refresh

            ecobee_token_response = ecobee_tokens(False, last_refresh_time)

            auth = ecobee_token_response[0]
            last_refresh_time = ecobee_token_response[1]

# Call EcoBee API to get data
# TODO refactor to use thermostat Summary / Runtime Revision and change wehn values update.
# TODO at some point estimate temperature (ML?)

            try:

                thermostat_url = 'https://api.ecobee.com/1/thermostat?'
                payload = {'json': '{"selection":{"selectionType":"registered","includeSensors":"true"}}'}
                header = {'Content-Type': 'application/json;charset=UTF-8', 'Authorization': auth}

                response = requests.get(thermostat_url, headers=header, params=payload)

                data = response.json()

            except:

                err_string = (str(timestamp) + 'Error in ecobee data call') + "\r"

                print(err_string)

                sleep(30)

                continue

#  Update temperature readings with error handling

            tempdict = get_sensors(data)

            if len(tempdict) == 0:

                print(data)
                sensor_error_count = sensor_error_count + 1

                if sensor_error_count == 1:

                    send_twilio_msg("Warning - sensor temps not updating")

                elif sensor_error_count == 11:

                    send_twilio_msg("Temp reading failure.  Program exited.")
                    sys.exit("Temp reading failure.  Program exited.")

                else:

                    pass

                sleep(60)

                continue

            else:

                if sensor_error_count > 0:

                    send_twilio_msg("Sensor issue resolved")

                else:

                    pass

                sensor_error_count = 0

                pass

#  Get Ohmconnect status TODO use: get_OC(http)


            try:

                oc_url = auth_dict['ohmconnect_url']

                r = http.request('GET', oc_url)

                data = r.data

                root = et.fromstring(data)

                oc_txt = root[1].text

                if oc_txt == 'True':

                    oc_state = True

                else:

                    oc_state = False

            except:

                oc_state = False

# Determine Ohmconnect state and setback offset
# TODO use dequeue instead

            oc.insert(0,oc_state)
            last_oc = oc.pop()

            if oc_state == last_oc:

                offset = 0

            elif oc_state == True:

                offset = setback

            else:

                offset = -setback

# Decision logic and set booleans for switches
# Plug status is updated separately from state to reduce calls to plug endpoints and allow rotation of heater operation

            offline_list = []

            rotate_active = rotate_plugnames

            for name in namelist:

# Determine high and low setpoints for iteration based on deadband and offset

                roomdict[name].temp = tempdict[name]

                roomdict[name].temp_low = setdict[name]
                roomdict[name].temp_high = setdict[name]+deadband

                roomdict[name].temp_high = roomdict[name].temp_high + offset
                roomdict[name].temp_low = roomdict[name].temp_low + offset

#  Determine each room's status (On or Off)

                if schedule(name,'All') is True:

                    if roomdict[name].temp == 999:

                        print('Warning:  bad temp reading in ', name)

                        roomdict[name].status = roomdict[name].status

                    elif roomdict[name].temp <= roomdict[name].temp_low:

                        roomdict[name].status = "ON"

                    elif roomdict[name].temp > roomdict[name].temp_high:

                        roomdict[name].status = "OFF"

                    else:

                        roomdict[name].status = roomdict[name].status

                else:

                    roomdict[name].status = "OFF"
                    print(name," Room Is Off")

# Update state for plugs in rotation

                if not rotate_active:  # Handles the case of an empty rotate_active list

                    pass

                elif name in rotate_active:

#                    print(rotate_active)  # For debugging

                    status = roomdict[name].status

                    plug_rotation_return = plug_rotation(rotate_active, plugdict, name, status, start_turn)

                    roomdict[name].status = plug_rotation_return[0]
                    rotate_active = plug_rotation_return[1]

                else:

                    pass

#  Set plug state from status, with rediscovery on fail

                try:

                    plugdict[name].state = roomdict[name].status

                except:

                    plugip = get_plugs(plugip, plugnames, named_flag)[0]

                    try:

                        plugdict[name] = SmartPlug(plugip[name])

                    except:

                        offline_list.append(name)

            start_turn = plug_rotation_return[2]+1

#            statusmsg = str(offline_list)+" Offline" #TODO bring statusmsg back

# Write console & log

            stat_str = "\n" + "Timestamp: " + str(timestamp) + "\n" +"\n"
            log_str = str(timestamp) + ", "

            for name in namelist:

                stat_str += (str(name) + " Set: " + str(roomdict[name].temp_low) + " Temp: " +
                          str(roomdict[name].temp) + " Heat: " + str(roomdict[name].status) + "\n")

                log_str  += (str(name) + ", " + str(roomdict[name].temp_low) + ", " +
                          str(roomdict[name].temp) + ", " + str(roomdict[name].status) + ", ")

# TODO bring statusmsg back here too

#            stat_str += ("Mode: " + statusmsg + "\n" + "Ohmconnect Status: " + str(oc_txt))

#            log_str += ("Mode: " + statusmsg + ", " + "Ohmconnect Status: " + str(oc_txt) + "\n")


            log = open("log.txt", "a+")
            log.write(log_str)
            log.close()

            print(stat_str + "\r")

            last_loop_sched = True

# If outside of the schedule enter sleep mode.  No logging in sleep mode.

        elif last_loop_sched is True and sched is False:

# Turn all plugs off if possible

            for name in namelist:

                try:

                    if roomdict[name].status == 'ON':

                        plugdict[name].state = 'OFF'
                        roomdict[name].status = plugdict[name].state
                        print(name, 'turned off')

                    else:

                        pass

                except:

                    overrun_warn_msg = str('Warning, {0} offline -- could not be turned off automatically'.format(name))

                    send_twilio_msg(overrun_warn_msg)
                    print(overrun_warn_msg)

            print('Sleep Mode')

            last_loop_sched = False

        else:

            pass

        sleep(looptime)

        continue
Exemple #7
0
#!/usr/bin/python3

#general imports
import time
import sys

#import needed for plug control
from pyHS100 import SmartPlug, SmartBulb
from pprint import pformat as pf

#ensure correct number of arguments are passed in
if len(sys.argv) != 2:
    print("please use this format:  morning_heat.py <time_in_minutes>")
    exit()

#assign aguements to variables
script_name = sys.argv[0]
on_time = int(sys.argv[1])

#abstracted variables
plug_ip = "10.0.2.41"

#instantiate plug object for heater
heater = SmartPlug(plug_ip)

#turn on for specified time
heater.state = "ON"
time.sleep(60 * on_time)
heater.state = "OFF"
Exemple #8
0
#!/usr/bin/env python
# coding=utf-8

# Step 1
import sys

from pyHS100 import SmartPlug, SmartBulb
from pprint import pformat as pf
 
plug = SmartPlug(sys.argv[1])
plug.state = sys.argv[2]