Beispiel #1
0
def scan(args):
    """Scan for sensors."""
    print('Scanning for 10 seconds...')
    devices = miflora_scanner.scan(BluepyBackend, 10)
    print('Found {} devices:'.format(len(devices)))
    for device in devices:
        print('  {}'.format(device))
Beispiel #2
0
def scan(args):
    """Scan for sensors."""
    print('Scanning for 10 seconds...')
    devices = miflora_scanner.scan(BluepyBackend, 10)
    print('Found {} devices:'.format(len(devices)))
    for device in devices:
        print('  {}'.format(device))
Beispiel #3
0
def scan(args):
    """Scan for sensors."""
    backend = _get_backend(args)
    print("Scanning for 10 seconds...")
    devices = miflora_scanner.scan(backend, 10)
    print("Found {} devices:".format(len(devices)))
    for device in devices:
        print(f"  {device}")
Beispiel #4
0
def scan(format='text'):
    """Scan for sensors."""
    if format == 'text': print('Scanning for 10 seconds...')
    devices = miflora_scanner.scan(BluepyBackend, 10)
    if format == 'text':
        print('Found {} devices:'.format(len(devices)))
        for device in devices:
            print('  {}'.format(device))
    elif format == 'json':
        print(json.dumps(devices, indent=1))
Beispiel #5
0
def search_bl_devices():
    """Scan for sensors."""
    devices_founded = []
    backend = BluepyBackend
    devices_mi = miflora_scanner.scan(backend, 12)
    logging.info('{} Geräte gefunden'.format(len(devices_mi)))
    for device in devices_mi:
        logging.info('{}'.format(device))
        devices_founded.append(Device(0, '', device))
    return devices_founded
Beispiel #6
0
    def floraScan(self):
        if fake:
            from fakeDomoticz import Devices
        Domoticz.Log("Scanning for Mi Flower Mate sensors")

        # databaseFile=os.path.join(os.environ['HOME'],'XiaomiMiFlowerMates')
        # first, let's get the list of devices we already know about
        database = shelve.open('XiaomiMiMates')
        database['filter'] = []
        filtered = database['filter']

        try:
            knownSensors = database['macs']
            oldLength = len(knownSensors)
            Domoticz.Debug("Already know something:" + str(oldLength))
            Domoticz.Log("Already known devices:" + str(knownSensors))
        except:
            knownSensors = []
            database['macs'] = knownSensors
            oldLength = 0
            Domoticz.Debug("No existing sensors in system?")

        # Next we scan to look for new sensors
        try:
            foundFloras = miflora_scanner.scan(BluepyBackend, 3)
            Domoticz.Log("Number of devices found via bluetooth scan = " +
                         str(len(foundFloras)))
        except:
            foundFloras = []
            Domoticz.Log("Scan failed")

        # set ignored devices
        for sensor in knownSensors:
            if sensor not in foundFloras:
                filtered.append(str(sensor))
        database['filter'] = filtered

        for sensor in foundFloras:
            if sensor not in knownSensors:
                knownSensors.append(str(sensor))
                Domoticz.Log("Found new device: " + str(sensor))

        if len(knownSensors) != oldLength:
            database['macs'] = knownSensors
            Domoticz.Log("Updating database")

        database.close()

        self.macs = knownSensors
        self.createSensors()
Beispiel #7
0
    def test_scan(self):
        """Test the scan function."""
        class _MockBackend(object):
            """Mock of the backend, always returning the same devices."""
            @staticmethod
            def scan_for_devices(_):
                return [
                    ('00:FF:FF:FF:FF:FF', None),
                    ('01:FF:FF:FF:FF:FF', 'Flower mate'),
                    ('02:FF:FF:FF:FF:FF', 'Flower care'),
                    ('c4:7c:8d:FF:FF:FF', 'random name'),
                ]

        devices = miflora_scanner.scan(_MockBackend, 0)
        self.assertEqual(len(devices), 3)
        self.assertEqual(devices[0], '01:FF:FF:FF:FF:FF')
        self.assertEqual(devices[1], '02:FF:FF:FF:FF:FF')
        self.assertEqual(devices[2], 'C4:7C:8D:FF:FF:FF')
    def test_scan(self):
        """Test the scan function."""
        class _MockBackend:  # pylint: disable=too-few-public-methods
            """Mock of the backend, always returning the same devices."""
            @staticmethod
            def scan_for_devices(_):
                """Mock for the scan function."""
                return [
                    ("00:FF:FF:FF:FF:FF", None),
                    ("01:FF:FF:FF:FF:FF", "Flower mate"),
                    ("02:FF:FF:FF:FF:FF", "Flower care"),
                    ("c4:7c:8d:FF:FF:FF", "random name"),
                ]

        devices = miflora_scanner.scan(_MockBackend, 0)
        self.assertEqual(len(devices), 3)
        self.assertEqual(devices[0], "01:FF:FF:FF:FF:FF")
        self.assertEqual(devices[1], "02:FF:FF:FF:FF:FF")
        self.assertEqual(devices[2], "C4:7C:8D:FF:FF:FF")
Beispiel #9
0
def main():
    try:
        scan_result = scan(BluepyBackend)
        # print(scan_result)
        sensors = []

        for mac in scan_result:
            try:
                poller = MiFloraPoller(mac, BluepyBackend, cache_timeout=60)
                temp = poller.parameter_value(MI_TEMPERATURE)
                moisture = poller.parameter_value(MI_MOISTURE)
                light = poller.parameter_value(MI_LIGHT)
                fer = poller.parameter_value(MI_CONDUCTIVITY)
                battery = poller.parameter_value(MI_BATTERY)
                firmware = poller.firmware_version()
                # print(f'temp: {temp}, moisture: {moisture}, light: {light}, battery: {battery}')
                miflora_sensor = {
                    'address': mac,
                    'firmwareInfo': {
                        'battery': battery,
                        'firmware': firmware
                    },
                    'sensorValues': {
                        'temperature': temp,
                        'lux': light,
                        'moisture': moisture,
                        'fertility': fer
                    },
                }

                sensors.append(miflora_sensor)

            except Exception as error:
                continue

        print_to_stdout(json.dumps(sensors))

    except Exception as error:
        print_to_stderr(error)
def main(args):
    """
    Check if running in debug mode
    """
    if args.debug:
        import debugpy
        print(
            "running in debug mode - waiting for debugger connection on {0}:{1}"
            .format(args.debugip, args.debugport))
        debugpy.listen((args.debugip, args.debugport))
        debugpy.wait_for_client()
    """
    # Parse PlugIn config file
    """
    if not os.path.exists(args.configfile):
        logging.critical("Plugin configuration file missing {0}".format(
            args.configfile))
        sys.exit(-1)

    pluginconfig = configparser.ConfigParser()
    pluginconfig.read(args.configfile)
    enabled = pluginconfig.get('MIFLORA', 'ENABLED')
    miniservername = pluginconfig.get('MIFLORA', 'MINISERVER')
    virtualUDPPort = int(pluginconfig.get('MIFLORA', 'UDPPORT'))
    pollFrequency = int(pluginconfig.get('MIFLORA', 'POLLFREQUENCY'))
    localtime = pluginconfig.get('MIFLORA', 'LOCALTIME')
    scanTimeout = 10
    udpenabled = pluginconfig.get('MIFLORA', 'UDPENABLED')
    mqttenabled = pluginconfig.get('MIFLORA', 'MQTTENABLED')
    mqttbroker = pluginconfig.get('MIFLORA', 'MQTTBROKER')
    mqttport = int(pluginconfig.get('MIFLORA', 'MQTTPORT'))
    mqtttopic = pluginconfig.get('MIFLORA', 'MQTTTOPIC')
    mqttusername = pluginconfig.get('MIFLORA', 'MQTTUSERNAME')
    mqttpassword = pluginconfig.get('MIFLORA', 'MQTTPASSWORD')

    mqttclient_id = "loxberry-miflora-{0}".format(random.randint(0, 1000))
    """
    transistion from general.cfg to general.json
    """
    if miniservername.startswith("MINISERVER"):
        miniserverID = miniservername.replace("MINISERVER", "")

    else:
        miniserverID = miniservername
        miniservername = "MINISERVER{0}".format(miniserverID)
    """
    check if general.json exists and Loxberry version > 2.2
    """
    lbsConfigGeneralJSON = os.path.join(Config.Loxberry("LBSCONFIG"),
                                        "general.json")
    lbsConfigGeneralCFG = os.path.join(Config.Loxberry("LBSCONFIG"),
                                       "general.cfg")

    if not os.path.exists(lbsConfigGeneralJSON):
        logging.warning(
            "gerneral.json missing in path {0}".format(lbsConfigGeneralJSON))
        logging.warning(
            "trying general.cfg instead {0}".format(lbsConfigGeneralCFG))

        if not os.path.exists(lbsConfigGeneralCFG):
            logging.critical("general.cfg not found in path {0}".format(
                lbsConfigGeneralCFG))
            sys.exit(-1)
        """
        general.cfg (legacy configuration file)
        """
        logging.info("using system configuration file {0}/general.cfg".format(
            Config.Loxberry("LBSCONFIG")))
        loxberryconfig = configparser.ConfigParser()
        loxberryconfig.read("{0}/general.cfg".format(
            Config.Loxberry("LBSCONFIG")))
        miniserverIP = loxberryconfig.get(miniservername, 'IPADDRESS')

    else:
        with open(lbsConfigGeneralJSON, "r") as lbsConfigGeneralJSONHandle:
            logging.info(
                "using system configuration file {0}/general.json".format(
                    Config.Loxberry("LBSCONFIG")))
            data = json.load(lbsConfigGeneralJSONHandle)

        # check if miniserver from plugin config exists in general.json
        if not miniserverID in data["Miniserver"].keys():
            logging.critical(
                "Miniserver with id {0} not found general.json - please check plugin configuration"
                .format(miniserverID))
            sys.exit(-1)

        miniserverIP = data["Miniserver"][miniserverID]["Ipaddress"]
        logging.info("Miniserver ip address: {0}".format(miniserverIP))
    """
    global variables
    """
    lastdatafile = '{0}/{1}/{2}'.format(Config.Loxberry("LBPDATA"),
                                        "xiaomi-miflora", "lastdata.dat")
    """
    exit if PlugIn is not enabled
    """
    if enabled != "1":
        logging.warning("Plugin is not enabled in configuration - exiting")
        sys.exit(-1)
    """
    if called with argument "daemon"
    """
    if args.daemon:

        # check if it is time to run - otherwise exit
        if (int(time.strftime("%H")) / pollFrequency).is_integer() == False:
            sys.exit(-1)
    """
    MQTT connect
    """
    if mqttenabled == "1":
        mqttclient = connect_mqtt(mqttbroker, mqttport, mqttclient_id,
                                  mqttusername, mqttpassword)

    # ---------------------------------------------
    # scan for Xiaomi MiFlora device
    # ---------------------------------------------
    logging.info(
        'Scanning for Xiaomi MiFlora devices (takes up to {0} seconds)'.format(
            scanTimeout))

    devices = miflora_scanner.scan(BluepyBackend, scanTimeout)

    logging.info('Found {0} devices:'.format(len(devices)))

    if len(devices) >= 1:
        """
        delete cached data file
        """
        if os.path.isfile(lastdatafile):
            os.remove(lastdatafile)
    """
    get data for each found sensor
    """
    for device in devices:
        devicemac = device.replace(":", "")

        logging.info('Polling device: {0}'.format(device))

        poller = MiFloraPoller(device, BluepyBackend)
        """
        Name
        """
        # build value string
        value = poller.name()

        # log data
        logging.info("{0}.{1}={2}".format(devicemac, "Name", value))

        # write value to lastdata.dat
        writelastdata(lastdatafile,
                      "{0}.{1}={2}".format(devicemac, "Name", value))

        # send value as udp datagram
        if udpenabled == "1":
            sendudp("{0}.{1}={2}".format(devicemac, "Name", value),
                    miniserverIP, virtualUDPPort)

        # publish MQTT topic
        if mqttenabled == "1":
            publish(mqttclient, "{0}/{1}/{2}".format(mqtttopic, devicemac,
                                                     "Name"), value)
        """
        PollTime
        """
        # Calculate offset based on 01.01.2009
        loxBaseEpoch = 1230768000

        # Use current time as polling time
        pollTime = int(time.time())

        # Convert time to localtime if enabled
        if localtime == "1":
            pollLocalTime = time.localtime(pollTime)

            pollTime = pollTime + pollLocalTime.tm_gmtoff

        # Subtract time / date offset
        loxSensorTime = pollTime - loxBaseEpoch

        # build value strings
        value = "{0}.{1}={2}".format(devicemac, "PollTime", loxSensorTime)

        # log data
        logging.info(value)

        # write value to lastdata.dat
        writelastdata(lastdatafile, value)

        # send value as udp datagram
        if udpenabled == "1":
            sendudp(value, miniserverIP, virtualUDPPort)

        # publish MQTT topic
        if mqttenabled == "1":
            publish(mqttclient, "{0}/{1}/{2}".format(mqtttopic, devicemac,
                                                     "PollTime"),
                    loxSensorTime)
        """
        PollTimeString
        """
        # Use current time as polling time
        timestamp = time.strftime("%d.%m.%Y %H:%M:%S",
                                  time.localtime(time.time()))

        # build value strings
        value = "{0}.{1}={2}".format(devicemac, "PollTimeString", timestamp)

        # log data
        logging.info(value)

        # write value to lastdata.dat
        writelastdata(lastdatafile, value)

        # send value as udp datagram
        if udpenabled == "1":
            sendudp(value, miniserverIP, virtualUDPPort)

        # publish MQTT topic
        if mqttenabled == "1":
            publish(
                mqttclient, "{0}/{1}/{2}".format(mqtttopic, devicemac,
                                                 "PollTimeString"), timestamp)

        # -------------------------------
        # Firmware
        # -------------------------------
        # build value string
        value = poller.firmware_version()

        # log data
        logging.info("{0}.{1}={2}".format(devicemac, "Firmware", value))

        # write value to lastdata.dat
        writelastdata(lastdatafile,
                      "{0}.{1}={2}".format(devicemac, "Firmware", value))

        # send value as udp datagram
        if udpenabled == "1":
            sendudp("{0}.{1}={2}".format(devicemac, "Firmware", value),
                    miniserverIP, virtualUDPPort)

        # publish MQTT topic
        if mqttenabled == "1":
            publish(mqttclient, "{0}/{1}/{2}".format(mqtttopic, devicemac,
                                                     "Firmware"), value)

        # -------------------------------
        # Temperature
        # -------------------------------
        # build value string
        value = poller.parameter_value(MI_TEMPERATURE)

        # log data
        logging.info("{0}.{1}={2}".format(devicemac, "Temperature", value))

        # write value to lastdata.dat
        writelastdata(lastdatafile,
                      "{0}.{1}={2}".format(devicemac, "Temperature", value))

        # send value as udp datagram
        if udpenabled == "1":
            sendudp("{0}.{1}={2}".format(devicemac, "Temperature", value),
                    miniserverIP, virtualUDPPort)

        # publish MQTT topic
        if mqttenabled == "1":
            publish(mqttclient, "{0}/{1}/{2}".format(mqtttopic, devicemac,
                                                     "Temperature"), value)

        # -------------------------------
        # Moisture
        # -------------------------------
        # build value string
        value = poller.parameter_value(MI_MOISTURE)

        # log data
        logging.info("{0}.{1}={2}".format(devicemac, "Moisture", value))

        # write value to lastdata.dat
        writelastdata(lastdatafile,
                      "{0}.{1}={2}".format(devicemac, "Moisture", value))

        # send value as udp datagram
        if udpenabled == "1":
            sendudp("{0}.{1}={2}".format(devicemac, "Moisture", value),
                    miniserverIP, virtualUDPPort)

        # publish MQTT topic
        if mqttenabled == "1":
            publish(mqttclient, "{0}/{1}/{2}".format(mqtttopic, devicemac,
                                                     "Moisture"), value)

        # -------------------------------
        # Light
        # -------------------------------
        # build value string
        value = poller.parameter_value(MI_LIGHT)

        # log data
        logging.info("{0}.{1}={2}".format(devicemac, "Light", value))

        # write value to lastdata.dat
        writelastdata(lastdatafile,
                      "{0}.{1}={2}".format(devicemac, "Light", value))

        # send value as udp datagram
        if udpenabled == "1":
            sendudp("{0}.{1}={2}".format(devicemac, "Light", value),
                    miniserverIP, virtualUDPPort)

        # publish MQTT topic
        if mqttenabled == "1":
            publish(mqttclient, "{0}/{1}/{2}".format(mqtttopic, devicemac,
                                                     "Light"), value)

        # -------------------------------
        # Conductivity
        # -------------------------------
        # build value string
        value = poller.parameter_value(MI_CONDUCTIVITY)

        # log data
        logging.info("{0}.{1}={2}".format(devicemac, "Conductivity", value))

        # write value to lastdata.dat
        writelastdata(lastdatafile,
                      "{0}.{1}={2}".format(devicemac, "Conductivity", value))

        # send value as udp datagram
        if udpenabled == "1":
            sendudp("{0}.{1}={2}".format(devicemac, "Conductivity", value),
                    miniserverIP, virtualUDPPort)

        # publish MQTT topic
        if mqttenabled == "1":
            publish(mqttclient, "{0}/{1}/{2}".format(mqtttopic, devicemac,
                                                     "Conductivity"), value)

        # -------------------------------
        # Battery
        # -------------------------------
        # build value string
        value = poller.parameter_value(MI_BATTERY)

        # log data
        logging.info("{0}.{1}={2}".format(devicemac, "Battery", value))

        # write value to lastdata.dat
        writelastdata(lastdatafile,
                      "{0}.{1}={2}".format(devicemac, "Battery", value))

        # send value as udp datagram
        if udpenabled == "1":
            sendudp("{0}.{1}={2}".format(devicemac, "Battery", value),
                    miniserverIP, virtualUDPPort)

        # publish MQTT topic
        if mqttenabled == "1":
            publish(mqttclient, "{0}/{1}/{2}".format(mqtttopic, devicemac,
                                                     "Battery"), value)

        logging.info("-------------------------------------------------")

    # exit with errorlevel 0
    sys.exit(0)
Beispiel #11
0
def scan(args, backend):
    print('Scanning for 10 seconds...')
    devices = miflora_scanner.scan(backend, 10)
    print('Found {} devices:'.format(len(devices)))
    for d in devices:
        print('  {}'.format(d))
#!/usr/bin/env python3.7

from btlewrap import BluepyBackend
from miflora import miflora_scanner 

backend = BluepyBackend
devices = miflora_scanner.scan(backend, 10)
print('Found {} devices:'.format(len(devices)))
for device in devices:
    print('{}'.format(device))
Beispiel #13
0
from miflora import miflora_scanner
from btlewrap.bluepy import BluepyBackend

print(miflora_scanner.scan(BluepyBackend))