Exemple #1
0
 def __init__(self, light_data):
     """Inits ButtonHandler by starting up a FlicClient to listen for button presses. Also creates a dictionary mapping click types to functions to handle them.
     
     Args:
         light_data: light information retrieved from the lightservice.
     """
     self.client = fliclib.FlicClient("localhost")
     self.data = light_data
     self.click_functions = {
         'ClickType.ButtonSingleClick': self._on_single_click,
         'ClickType.ButtonDoubleClick': self._on_double_click,
         'ClickType.ButtonHold': self._on_hold
     }
     self.buttons = {}
     self.actions = {}
     self.states = {}
     
     self.light_service = None
#!/usr/bin/env python3

# Scan Wizard application.
#
# This program starts scanning of new Flic buttons that have not previously been verified by the server.
# Once it finds a button that is in private mode, it shows a message that the user should hold it down for 7 seconds to make it public.
# Once it finds a button that is in public mode, it attempts to connect to it.
# If it could be successfully connected and verified, the bluetooth address is printed and the program exits.
# If it could not be verified within 30 seconds, the scan is restarted.

import fliclib

client = fliclib.FlicClient("localhost")


def on_found_private_button(scan_wizard):
    print(
        "Found a private button. Please hold it down for 7 seconds to make it public."
    )


def on_found_public_button(scan_wizard, bd_addr, name):
    print("Found public button " + bd_addr + " (" + name +
          "), now connecting...")


def on_button_connected(scan_wizard, bd_addr, name):
    print("The button was connected, now verifying...")


def on_completed(scan_wizard, result, bd_addr, name):
    # input('press key...')
    # onFlicButtonClickOrHold(
    #     fliclib.ButtonConnectionChannel(BLACK_BUTTON_ADDRESS),
    #     fliclib.ClickType.ButtonClick,
    #     False,
    #     0
    # )
    # while True:
    #     pass

    try:
        logger.info('Setting up Flic client...')

        flicButtonConnectionChannels = []

        flicClient = fliclib.FlicClient('localhost')
        flicClient.get_info(onFlicGetInfo)
        flicClient.on_new_verified_button = onFlicNewVerifiedButton
        flicClient.on_bluetooth_controller_state_change = \
            onFlicBluetoothControllerStateChange
    except Exception as e:
        logger.error('Failed to start Flic client: {}'.format(e))
        exit(1, forceQuitCaster=True)
    else:
        caster.setup(logLevel=logger.level, errorHandler=onCasterError)

    logger.info('Ready - waiting for button clicks...\n---')

    # note that this method is blocking!
    flicClient.handle_events()
Exemple #4
0
def reset_client_and_scan():
    client = fliclib.FlicClient("localhost")
    scan_for_button(client)
Exemple #5
0
def run():
    # set up logging
    logger = logging.getLogger(__name__)
    try:
        logging_level = sys.argv[1].upper()
    except IndexError:
        logging_level = 'INFO'
    logging.basicConfig(
        filename=config.LOG_FILENAME,
        level=logging_level,
        format='%(asctime)-12s | %(levelname)-8s | %(name)s | %(message)s',
        datefmt='%d/%m/%y, %H:%M:%S')

    print("Starting light controller, press [Ctrl+C] to exit.")
    logger.info("Starting light controller...")

    # signal handler to exit gracefully on Ctrl+C
    def exit_handler(signal, frame):
        print('Exiting...', end='')
        logger.info('Exiting...')
        presence_sensor.stop()
        flic_client.close()
        flic_thread.join()
        print(' OK')
        logger.info(' OK')
        sys.exit(0)

    signal.signal(signal.SIGINT, exit_handler)

    # these lights always come on when one of us gets home
    welcome_lights = ['Hall 1', 'Hall 2', 'Dining table', 'Kitchen cupboard']

    # these functions are called by the PresenceSensor on last-one-out or first-one-in events
    def welcome_home(beacon_owner):
        logger.info('Welcome home %s!' % (beacon_owner))
        if daylight_sensor.query():
            bridge.light_on(welcome_lights)
        else:
            bridge.light_on([])

    def bye():
        logger.info("There's no-one home, turning lights off...")
        bridge.light_off([])

    # these functions are called by the Flic client when a button is pressed, a new button is found etc.
    def click_handler(channel, click_type, was_queued, time_diff):
        logger.info(channel.bd_addr + " " + str(click_type))
        if str(click_type) == 'ClickType.ButtonSingleClick':
            if channel.bd_addr in groups.keys():
                logger.info("Switching on lights associated with button " +
                            channel.bd_addr)
                bridge.light_on(groups[channel.bd_addr]['group'])
            else:
                logger.debug('%s Button not registered with any lights' %
                             (channel.bd_addr))
        elif str(click_type) == 'ClickType.ButtonHold':
            # turn off all lights
            logger.info("Turning off all lights...")
            bridge.light_off([])
        elif str(click_type) == 'ClickType.ButtonDoubleClick':
            # not used
            pass

        return

    def got_button(bd_addr):
        cc = fliclib.ButtonConnectionChannel(bd_addr)
        # Assign function to call when a button is clicked
        cc.on_button_single_or_double_click_or_hold = click_handler
        cc.on_connection_status_changed = \
         lambda channel, connection_status, disconnect_reason: \
          logger.info(channel.bd_addr + " " + str(connection_status) + (" " + str(disconnect_reason) if connection_status == fliclib.ConnectionStatus.Disconnected else ""))
        flic_client.add_connection_channel(cc)
        print(' OK')
        logger.info(bd_addr + ' OK')

    def got_info(items):
        print('Connecting Flic buttons')
        for bd_addr in items["bd_addr_of_verified_buttons"]:
            print(bd_addr, end=' ...')
            got_button(bd_addr)

    # initialise lights bridge
    bridge = lights.Bridge(hue_uname=config.HUE_USERNAME, lightify=True)

    # load flic button groups from file
    with open(config.FLIC_BUTTONS) as f:
        json_data = f.read()
    groups = json.loads(json_data)

    # create flic client and start in new thread
    flic_client = fliclib.FlicClient("localhost")
    logger.info('Connecting Flic buttons...')
    flic_client.get_info(got_info)
    flic_client.on_new_verified_button = got_button
    flic_thread = threading.Thread(target=flic_client.handle_events)
    flic_thread.start()

    # initialise daylight sensor (daylight times from sunrise-sunset.org API)
    daylight_sensor = lights.DaylightSensor(lat=config.LATITUDE,
                                            lon=config.LONGITUDE)
    print('Sunrise and sunset times... OK')

    # initialise presence sensor and register beacons
    print('Starting presence sensor...', end='')
    logger.info('Starting presence sensor...')
    presence_sensor = presence.PresenceSensor(welcome_callback=welcome_home,
                                              last_one_out_callback=bye)
    beacon1 = {
        "UUID": "FDA50693-A4E2-4FB1-AFCF-C6EB07647825",
        "Major": "10004",
        "Minor": "54480"
    }
    beacon2 = {
        "UUID": "FDA50693-A4E2-4FB1-AFCF-C6EB07647825",
        "Major": "10004",
        "Minor": "54481"
    }
    logger.info((presence_sensor.register_beacon(beacon1, "Richard")))
    logger.info((presence_sensor.register_beacon(beacon2, "Michelle")))
    presence_sensor.start()  # starts looping in a new thread
    print(' OK')

    # initialise lights controller (triggers timed actions)
    print('Starting light controller...', end='')
    controller = lights.Controller(bridge, config.RULES, daylight_sensor,
                                   presence_sensor)
    print(' OK')

    while True:
        # loop controller to check if any actions should be triggered
        controller.loop_once()
        time.sleep(1)
import traceback
from logging import handlers

from eventhelper import EventHelper  # @UnresolvedImport

FLIC_LIB_PATH = "/home/pi/fliclib-linux-hci/clientlib/python/"
sys.path.append(FLIC_LIB_PATH)
import fliclib  # @UnresolvedImport

FLIC_HOST = "localhost"
LOGPATH = os.path.dirname(
    os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
FILELOGLEVEL = logging.INFO
CONSOLELOGLEVEL = logging.WARN

flicClient = fliclib.FlicClient(FLIC_HOST)

eventhelper = EventHelper()


def initLogger(loggerName, logPath, fileLogLevel, consoleLogLevel):
    logger = logging.getLogger(loggerName)
    loggerLevel = min(fileLogLevel, consoleLogLevel)
    logger.setLevel(loggerLevel)
    logFormatter = logging.Formatter(
        "%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s]  %(message)s")
    fileHandler = handlers.TimedRotatingFileHandler(logPath,
                                                    when='D',
                                                    backupCount=7)
    fileHandler.setFormatter(logFormatter)
    fileHandler.setLevel(fileLogLevel)
Exemple #7
0
def new_scan_wizard_thread():

	msg = ("New scan wizard thread..")
	print(msg)
	socketio.emit('scan wizard', msg)

	wizard_client = fliclib.FlicClient(host)

	# db_sw_deamon = sqlite3.connect('../bin/armv6l/flicd.sqlite.db')
	# db_sw_flicpi =  sqlite3.connect('flicpi.db')

	def on_found_private_button(scan_wizard):
		msg = ("Found a private button. Please hold it down for 7 seconds to make it public.")
		print(msg)
		socketio.emit('scan wizard', msg)

	def on_found_public_button(scan_wizard, bd_addr, name):
		msg = ("Found public button " + bd_addr + " (" + name + "), now connecting...")
		print(msg)
		socketio.emit('scan wizard', msg)

	def on_button_connected(scan_wizard, bd_addr, name):
		msg = ("The button was connected, now verifying...")
		print(msg)
		socketio.emit('scan wizard', msg)

	def on_completed(scan_wizard, result, bd_addr, name):
		msg = ("Scan wizard completed with result " + str(result) + ".")
		print(msg)
		socketio.emit('scan wizard', msg)



		if result == fliclib.ScanWizardResult.WizardSuccess:
			
			db_flicpi.execute("INSERT INTO users VALUES (?, ?, ?, ?)", (datetime.now(), bd_addr, None, None)).commit()

			msg = ("Your button is now ready. The bd addr is " + bd_addr + ".")
			print(msg)
			socketio.emit('scan wizard', msg)
			
			color = db_flicdeamon.execute("SELECT color FROM buttons WHERE bdAddr = ?", (bd_addr, )).fetchone()
			
			data = {
			 'bdAddr': bd_addr,
			 'color': color
			}
			socketio.emit('scan wizard succes', data)

		wizard_client.close()

	wizard = fliclib.ScanWizard()
	wizard.on_found_private_button = on_found_private_button
	wizard.on_found_public_button = on_found_public_button
	wizard.on_button_connected = on_button_connected
	wizard.on_completed = on_completed
	wizard_client.add_scan_wizard(wizard)

	msg = ("Welcome to Scan Wizard. Please press your Flic button.")
	print(msg)
	socketio.emit('scan wizard', msg)

	wizard_client.handle_events()
Exemple #8
0
def background_thread():

	print("Running T...")

	client = fliclib.FlicClient(host)
	# db = sqlite3.connect('flicpi.db')


	def got_button(bd_addr):
		cc = fliclib.ButtonConnectionChannel(bd_addr)
		cc.on_button_single_or_double_click_or_hold = \
			lambda channel, click_type, was_queued, time_diff: \
				handle_click_type(channel.bd_addr, click_type)

		cc.on_connection_status_changed = \
			lambda channel, connection_status, disconnect_reason: \
				print(channel.bd_addr + " " + str(connection_status) + (" " + str(disconnect_reason) if connection_status == fliclib.ConnectionStatus.Disconnected else ""))
		client.add_connection_channel(cc)


	def got_info(items):
		print(items)
		for bd_addr in items["bd_addr_of_verified_buttons"]:
			got_button(bd_addr)


	def handle_click_type(bdAddr, click_type):

		if click_type is fliclib.ClickType.ButtonSingleClick:
			handle_single_click(bdAddr)
		else:
			print("No process to handle click type:",  str(fliclib.ClickType))


	def handle_single_click(bdAddr):


		timestamp, status = get_last(bdAddr)

		
		if status:
			session_length = (datetime.now() - timestamp).total_seconds()
			print(bdAddr + " session lasted: " + str(session_length) + '.')

			

			user = db_flicpi.execute("SELECT user FROM users WHERE bdAddr = ? ORDER BY ROWID DESC LIMIT 1", (bdAddr,)).fetchone()
			
			if user is not None:
				user = user[0]

			new_entry = {
				'timestamp': str(timestamp),
				'bdAddr': bdAddr,
				'user': user,
				'session_length': session_length,
			}

			cur = db_flicpi.cursor()
			cur.execute("INSERT INTO sessions (timestamp, bdADdr, user, session_length) VALUES (?, ?, ?, ?)", (new_entry['timestamp'], new_entry['bdAddr'], new_entry['user'], new_entry['session_length']))
			new_entry['key'] = cur.execute("SELECT key FROM sessions ORDER BY ROWID DESC LIMIT 1").fetchone()[0]
			db_flicpi.commit()

			new_entry['session_length_rendered'] = secs_to_string(session_length)

			socketio.emit('new session', new_entry)
			get_graph_history()

		else:
			print(bdAddr, "session starting...")

		db_flicpi.execute("INSERT INTO events (timestamp, bdAddr, status) VALUES (?, ?, ?)", (datetime.now(), bdAddr, not status, ))
		db_flicpi.commit()

		update_state_tabe()
		

	def get_last(bdAddr):
		""" 
		Get the last entry of this bdAddr in event_log. 
		Return the status and the time of log.
		If does not exist return False and datetime.now().
		"""

		row = db_flicpi.execute("SELECT timestamp, status FROM events WHERE bdAddr=? ORDER BY timestamp DESC LIMIT 1", (bdAddr, )).fetchone()		

		if row is not None:
			return dateutil.parser.parse(row[0]), bool(row[1])

		return (datetime.now(), False)

	client.get_info(got_info)
	client.on_new_verified_button = got_button
	client.handle_events()
Exemple #9
0
 def __init__(self):
     """Inits ConfigButtonHandler by starting up a FlicClient to listen for button presses.
     """
     self.client = fliclib.FlicClient("localhost")