Beispiel #1
0
def sensor_export():

    output = {}

    for sensor in sensors:

        voltage, wattage = [0, 0]

        # Get Sensor Object:
        try:
            sensor_object = pyHS100.SmartPlug(sensors[sensor])
            consumption = sensor_object.get_emeter_realtime()
            voltage, wattage = consumption['voltage_mv'] / 1000, consumption[
                'power_mw'] / 1000

        except Exception as e:
            print('Error: Cannot get power status on %s. %s' % (sensor, e))

        finally:
            energy = energy_calculator(wattage)
            output.update({
                sensor: {
                    'volts': voltage,
                    'watts': wattage,
                    'kwh': energy[0],
                    'day_rate': energy[1]
                }
            })

    return output
Beispiel #2
0
def device_setup():
    global plug, denon, roku, trigger_map
    trigger_map = TriggerMap()
    denon = DenonConnection(device_details.denon_ip_address(), "23", trigger_map)
    roku = Roku.discover(timeout=5)[0]
    plug_ip = list(pyHS100.Discover().discover())[0]
    plug = pyHS100.SmartPlug(plug_ip)
    def check_recording(self, ):
        """
        call helper thread, best or ok in main -- used by smart_plug not smart_plug_graphing
        if recording then record the data in db
        for now do not assume timer is running
        call from ht polling action
        """
        msg = "SmartPlugAdapter.check_recording  "
        AppGlobal.log_if_wrong_thread(threading.get_ident(),
                                      msg=msg,
                                      main=False)

        if not (self.recording or self.monitor):
            return

#        msg    =  f"?ht? adapter check_recording "
#        AppGlobal.what_thread( threading.get_ident(), msg, 20  )

        now = time.time()
        if now < self.next_record_time:  # or monitor time
            return

        self.last_record_time = now
        self.next_record_time = now + self.delta_t
        try:
            plug = pyHS100.SmartPlug(self.tcpip)
            plug_data = plug.get_emeter_realtime()

            # ?? could add plug state - on off,.....

            # id          = f"{self.name}{self.last_record_time}r"
            # print   ( f"record data {id}:{plug_data})" )
            rnd = "%.2f" % plug_data["power"]
            msg = f'{rnd} watts'  #!! bit of rounding would be nice here
            self.gui_tk_label_2.config(text=msg)

        except pyHS100.smartdevice.SmartDeviceException as exception:  # look up correct exception
            self.timer_on = False
            #self.record_off()  to much messaging and will throw own error
            msg = f"failed to communicate with plug - record off for: {self.name} {self.tcpip}"

            AppGlobal.gui.print_info_string(msg)
            return

        if AppGlobal.graph_live_flag and self.monitor and self.live_graph_ready:
            #            print( "check_recording" )
            self.graphing_new_data = True
            #!! normalized and unnormalize data
            self.gd_time.append(self.last_record_time)
            self.gd_time_adj.append(
                AppGlobal.graph_live.rescale_time_function(
                    self.last_record_time))  #?? make local ref??
            self.gd_power.append(plug_data["power"])

        if self.recording:
            db_data = ((self.name, self.last_record_time, "r", "?",
                        plug_data["voltage"], plug_data["current"],
                        plug_data["power"], plug_data["total"]), )
            self.insert_measurements(db_data)
Beispiel #4
0
def get_light_state():
    ''' Provides a helper to get the external light state (boolean). '''
    plug = SmartHome.SmartPlug(SENSOR_IP_LIGHT)

    # Where 0.0 is 'Light Off' and 1.0 is 'Light On'.
    if plug.get_sysinfo()['relay_state'] == 0:
        return 0.0
    else:
        return 1.0
Beispiel #5
0
def get_smartplug_state(name):

    from lumacode import get_smartdevices

    try:
        device = pyHS100.SmartPlug(
            get_smartdevices.address(category='smartplugs', name=name))
        state = remap_state(device.state)

    except Exception as e:
        state = 0
        print('Error on %s: %s' % (name, e))

    return state
 def on(self, ):
     """
     mutator
     plug on call from ht or gt
     manage exception: plug might not be there .......
     """
     try:
         plug = pyHS100.SmartPlug(self.tcpip)
         plug.turn_on()
         self.display_msg("Plug On")
     except pyHS100.smartdevice.SmartDeviceException as exception:
         msg = "failed to communicate with plug"
         self.display_msg(msg)
         msg = msg + ": " + self.name
         AppGlobal.gui.print_info_string(msg)
Beispiel #7
0
 def api_state(self):
     plug = pyHS100.SmartPlug("192.168.0.109")
     if request.method == 'POST':
         # POST requests are for setting the light state
         light_state_actions = {True: plug.turn_on, False: plug.turn_off}
         light_state = request.form.get('light_state', 'false') == "true"
         light_state_actions[light_state]()
         #set_state_on = 'light_state' in request.form.keys() and request.form.get('light_state', 'false') == "true"
         #if set_state_on:
         #    plug.turn_on()
         #else:
         #    plug.turn_off()
         return ('', 204)
     elif request.method == 'GET':
         # GET requests are for reading the light state
         return_dict = {"light_state": plug.state == "ON"}
         return json.dumps(return_dict)
Beispiel #8
0
def get_full_info( tcpip ):
    """
    !! get info from a device
    return an ordered dict of all info we know how to get from device
    if device not found then will have full_info["device"]     = "failed to communicate" and length <= 3

    """
    #print("get_full_info")
    full_info              = {}
    full_info["tcpip"]     = tcpip
    try:
        plug                  = pyHS100.SmartPlug( tcpip )
        # some info may be duplicated but that just loweres efficiency

        # additional dicts
        add_dict              = plug.hw_info
        full_info.update( add_dict )

        full_info.update( plug.sys_info )
        full_info.update( plug.location )
        full_info.update( plug.timezone )

        # additional individual items
        full_info["alias"]                    = plug.alias
        full_info["device_type"]              = plug.device_type
        full_info["time"]                     = plug.time
        full_info["is_plug"]                  = plug.is_plug
        full_info["is_strip"]                 = plug.is_strip
        full_info["is_variable_color_temp"]   = plug.is_variable_color_temp
        full_info["is_bulb"]                  = plug.is_bulb

    except Exception as exception:             # look up correct exception
        pass   # point here is just to skip it
#        msg         = "full_info failed to communicate with plug"
#        print( f"type(exception ) {exception} " )
        full_info["device"]     = "failed to communicate"
        # log?
        #print( msg )
        #raise
    # consider a sort into an ordered dict
    #return full_info
    od = collections.OrderedDict( sorted( full_info.items(), key=lambda t: t[0] ))
    return od
Beispiel #9
0
def scan_for_plugs( start_tcpip, start_tcpip_ix, end_tcpip_ix, max_plugs = 0, msg_function = None ):
    """
    scan a range of tcpip address for plugs
    scan_for_plugs( "192.168.0.", 209, 210, max_plugs = 0 ):
    msg_function   a function of one arg with a string as msg see call_msg_function ... None and it is ignored

    a plug is anything that responds to the plug protocol
    seems to take on order of 5 sec for each attempt that fails
    return list of tcpip address with plugs
    could use function scan_a_plug but not really much code saved ??
    """
    found_list   = []
    for ix in range( start_tcpip_ix, end_tcpip_ix ):
        tcpip    = f"{start_tcpip}{ix}"
        msg      = f"probe: {tcpip}"
        call_msg_function( msg_function, msg )
        try:
            plug            = pyHS100.SmartPlug( tcpip )
            info            = plug.hw_info
            msg      = f"found device at: {tcpip}"
            call_msg_function( msg_function, msg )
            found_list.append( tcpip )

            if max_plugs == 0:
                continue
            if len( found_list )  >= max_plugs:
                break

#    #                print( msg  )
#                    AppGlobal.gui.print_info_string( msg )
        # may save event
#            full_info = "no info"
#            full_info = self.get_full_info( tcpip )
#            print( full_info )
        #except Exception as exception:             # look up correct exception
        except pyHS100.smartdevice.SmartDeviceException  as exception:
            print( f"{type(exception )} {exception} " )
            msg         = f"failed to communicate with plug at {tcpip}"
            print( msg )
            msg      = f"     no device at: {tcpip}"    # indented
            call_msg_function( msg_function, msg )
    return found_list
Beispiel #10
0
def scan_a_plug(  tcpip, msg_function = None ):
    """
    scan a range of tcpip address for plugs
    scan_for_plugs( "192.168.0.", 209, 210, max_plugs = 0 ):
    msg_function   a function of one arg with a string as msg see call_msg_function ... None and it is ignored

    a plug is anything that responds to the plug protocol
    seems to take on order of 5 sec for each attempt that fails
    return list of tcpip address with plugs
    """
    ret      = False   # True if plug is found at the tcpip
    msg      = f"probe: {tcpip}"
    call_msg_function( msg_function, msg )
    try:
        plug            = pyHS100.SmartPlug( tcpip )
        info            = plug.hw_info
        ret             = True
    except pyHS100.smartdevice.SmartDeviceException  as exception:
        print( f"{type(exception )} {exception} " )
        msg         = f"failed to communicate with plug at {tcpip}"
        print( msg )
    return ret
 def off(self, ):
     """
     mutator
     off from on or from timer running, may have a conflict as this may be called from
     either thread ht or gt
     if timer is on turn it off
     """
     try:
         self.timer_on = False
         plug = pyHS100.SmartPlug(self.tcpip)
         plug.turn_off()
         self.display_msg("Plug Off")
         if self.timer_on:
             self.timer_on = False
             msg = "Plug off and Timer Off"
             #                print( msg  )
             AppGlobal.gui.print_info_string(msg)
     # may save event
     except pyHS100.smartdevice.SmartDeviceException as exception:
         msg = "failed to communicate with plug {self.tcpip}"
         self.display_msg(msg)
         msg = msg + ": " + self.name
         AppGlobal.gui.print_info_string(msg)
Beispiel #12
0
def monitorDevice(config, device):
    try:
        state = State.AWAKE
        next_state = state
        retries = 0
        notify_state = NotifyState.ONLINE

        while True:
            previous_state = state
            state = next_state

            if state == State.AWAKE:
                try:
                    host = socket.gethostbyname(device.host)
                    socket.create_connection((host, device.port),
                                             SOCKET_TIMEOUT).close()

                    if notify_state != NotifyState.ONLINE:
                        notify_state = NotifyState.ONLINE
                        notify(config,
                               '{device.name} is ONLINE',
                               device = device)

                    if previous_state != state.AWAKE or retries > 0:
                        log('Device is now up', device = device)

                    retries = 0
                except (socket.timeout, socket.error, ConnectionError):
                    log('No response, attempt {attempt}/{device.retries}',
                        device = device,
                        attempt = retries + 1)

                    retries = retries + 1
                    if retries >= device.retries:
                        if notify_state != NotifyState.OFFLINE:
                            notify_state = NotifyState.OFFLINE
                            notify(config,
                                   '{device.name} is OFFLINE',
                                   device = device)
                        next_state = State.POWERING_OFF
                        continue

                time.sleep(device.check_interval)

            elif state == State.POWERING_OFF:
                try:
                    host = socket.gethostbyname(device.plug_host)
                    pyHS100.SmartPlug(host).turn_off()
                    log('Powered off', device = device)
                    next_state = State.POWER_OFF
                except (pyHS100.SmartDeviceException, socket.error) as e:
                    log('Failed to power off: {exception}',
                        device = device,
                        exception = e)

                    # Sleep, unless this was caused by a timeout
                    if not isinstance(e.__cause__, socket.timeout):
                        time.sleep(SOCKET_TIMEOUT)

            elif state == State.POWER_OFF:
                log('Waiting {device.cycle_time} seconds for power cycle',
                    device = device)
                time.sleep(device.cycle_time)
                next_state = State.POWERING_ON

            elif state == State.POWERING_ON:
                try:
                    host = socket.gethostbyname(device.plug_host)
                    pyHS100.SmartPlug(host).turn_on()
                    log('Powered on', device = device)
                    next_state = State.REBOOTING
                except (pyHS100.SmartDeviceException, socket.error) as e:
                    log('Failed to power on: {exception}',
                        device = device,
                        exception = e)

                    # Sleep, unless this was caused by a timeout
                    if not isinstance(e.__cause__, socket.timeout):
                        time.sleep(SOCKET_TIMEOUT)

            elif state == State.REBOOTING:
                log('Waiting {device.boot_time} seconds for reboot',
                    device = device)
                time.sleep(device.boot_time)
                next_state = State.AWAKE
                retries = 0

    except Exception as e:
        log('Got exception while monitoring: {exception}',
            device = device,
            exception = e)
# Collection of functions for interfacing with smart devices

# pyHS100 library for TP-Link devices
import pyHS100
from threading import Thread

# Initialise smart device objects
bedside_light = pyHS100.SmartPlug('10.0.0.61')
sound_system = pyHS100.SmartPlug('10.0.0.62')

# Dictionary storing states - True = on
smart_device_states = {bedside_light: False, sound_system: False}

# Body head and tail
body_head = (b'<body bgcolor=white>' +
             b'<p>Basic control of network connected devices</p>')
body_tail = b'</body>'

# HTML link syntax repeatable parts
link_0 = b'<a href="'
link_1 = b'"><img src="'
link_2 = b'" style="width:200px;height:120px;border:0;"></a>'
'''
function to return a dictionary with the states of the smart devices
'''


def getDeviceStates():
    smart_device_states['bedside_light'] = bedside_light.is_on
    smart_device_states['sound_system'] = sound_system.is_on
    return smart_device_states
Beispiel #14
0
logger = logging.getLogger(__name__)
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    filename=FILENAME,
    level=logging.INFO)

logger.setLevel(
    logging.INFO)  #change to logging.DEBUG or logging.INFO or logging.CRITICAL

t_TOKEN = "xxx"
t_CHATID = xxx

plug_LIGHT = "xxx.xxx.xxx.xxx"
plug_DESKTOP = "xxx.xxx.xxx.xxx"

p_light = pyHS100.SmartPlug(plug_LIGHT)
p_desktop = pyHS100.SmartPlug(plug_DESKTOP)

light_name = ['light', 'living room', 'living room light']
desk_name = ['desk', 'desktop']


def flip_state(p_obj):
    if p_obj.state == 'ON':
        p_obj.turn_off()
        return p_obj.state
    else:
        p_obj.turn_on()
        return p_obj.state

Beispiel #15
0
    def cb_device_action( self, button_ix, action  ):
        """
        process devices perhaps on, off timer , see lambda setup in button creation
        maybe decode string in adapter as well
        """
#        print( f"controller.cb_device_action {button_ix}, {action}" )

        # check for valid index -- may be overly defensive, but so what
        if button_ix < len( AppGlobal.device_list ):
            i_device    = AppGlobal.smartplug_adapter_list[ button_ix ]
            tcpip       = i_device.tcpip
            plug        = pyHS100.SmartPlug( tcpip )
        else:
            msg      = f"invalid device index{button_ix}"
            self.gui.print_info_string( msg )
            self.logger.info( msg )
            return

        # test getting time
#        gui_combo      = i_device.gui_tk_combo
#        combo_contents = gui_combo.get()
#        print(f"combo_contents: {combo_contents}, {type(combo_contents)}")

        # wrap actions in try except and capture error info
        if   action == "info":
            # move code to device adapter
            #self.gui.print_info_string( tcpip )
            #info    = str( plug.hw_info )  # need to process this into something nice -- is this subset of get_sysinfo()
            info    = "Full device info: \n" + plug_util.dict_to_str(  plug_util.get_full_info( tcpip ) )

            #print( type( info ) )
            self.gui.print_info_string( info  )

        elif action == "start":   # may make synonymous with on ??
            i_device.start_timer()

        elif action == "cb_on":
            i_device.cb_on()

        elif action == "mon":
            i_device.cb_mon()

        elif action == "record":
            i_device.cb_record()

        elif action == "on":
            i_device.on()

        elif action == "off":
            i_device.off()
#            msg     = f"Plug is_on: {plug.is_on }"
#            self.gui.print_info_string( msg )

        elif action == "record_on":
            # !! check first for db file exists
            i_device.record_on()
#            msg      = f"Record on plug is on : {plug.is_on }"
#            self.gui.print_info_string( msg )

        elif action == "record_off":
            i_device.record_off()
#            msg     = f"Record off plug is on : {plug.is_on }"
#            self.gui.print_info_string( msg )

        else:
            msg      = f"invalid action {action}"
            self.gui.print_info_string( msg )