Exemple #1
0
def main():

    mothership_url = birdhouse_utils.make_mothership_url(args, config)
    tbapi = TbApi(mothership_url, thingsboard_username, thingsboard_password)

    print(f"Retrieving template dashboard {template_dash}... ",
          end='',
          flush=True)
    template_dash_def = tbapi.get_dashboard_definition(
        tbapi.get_dashboard_by_name(template_dash))

    # We also need the id of the device being swapped out
    template_device_id = tbapi.get_id(
        tbapi.get_device_by_name(
            birdhouse_utils.make_device_name(args["<device>"])))

    print(" done.")

    all_devices = tbapi.get_devices_by_name(copy_to_pattern)

    for device in all_devices:
        num = birdhouse_utils.get_device_number_from_name(device["name"])

        print(f"Updating dashboard for {device['name']}")
        dash_name_being_replaced = birdhouse_utils.make_dash_name(num)
        device_name = birdhouse_utils.make_device_name(num)
        device = tbapi.get_device_by_name(device_name)
        device_id = tbapi.get_id(device)

        # The dash we are replacing:
        dash_being_replaced = tbapi.get_dashboard_by_name(
            dash_name_being_replaced)
        dash_id_being_replaced = tbapi.get_id(dash_being_replaced)

        dash_def = tbapi.get_dashboard_definition(
            tbapi.get_dashboard_by_name(
                template_dash))  # dash_def will be modified
        birdhouse_utils.reassign_dash_to_new_device(dash_def,
                                                    dash_name_being_replaced,
                                                    template_device_id,
                                                    device_id, device_name)

        dash_def["id"]["id"] = dash_id_being_replaced

        # del_humidity(dash_def)
        # exit()

        tbapi.save_dashboard(dash_def)
Exemple #2
0
    def on_birdhouse_number_changed(self):
        """ Immediate response to birdhouse number changing """
        if self.initializing: return

        num = self.layout.find_widget('birdhouse_number').value
        self.layout.find_widget(
            'local_ssid').value = birdhouse_utils.make_device_name(num)
def check_for_remigration(to_do_list):
    """
    Make sure we're not queueing up a device we've already migrated
    """
    tbapi_old = TbApi(birdhouse_utils.make_mothership_url(old_server_ip),
                      thingsboard_username, thingsboard_password)
    tbapi_new = TbApi(birdhouse_utils.make_mothership_url(new_server_ip),
                      thingsboard_username, thingsboard_password)

    old_client = create_client(old_server_ip)
    new_client = create_client(new_server_ip)

    print(
        "Conducting remigration checks (to make sure device hasn't already been migrated to new server)"
    )

    for num in to_do_list:
        print(".", end="")
        name = birdhouse_utils.make_device_name(num)

        if not device_has_data(tbapi_old, old_client, name):
            print(
                f"\nThere is no data on the old server for device {name}.  Nothing to migrate."
            )
            exit()

        if device_has_been_migrated(tbapi_old, old_client, tbapi_new,
                                    new_client, name):
            print(f"\nDevice {name} has already been migrated.")
            exit()
    print()
Exemple #4
0
def get_default_values(settings):
    device_name = birdhouse_utils.make_device_name(settings.birdhouse_number)
    return {
        'temperatureCalibrationFactor': (1,                          '["calibrationFactors"]["temperatureCalibrationFactor"]', None,               'float'),
        #      Parameter name                  Initial value              Path to item in JSON returned from REST server     Corresponding settings var
        'temperatureCalibrationOffset': (0,                          '["calibrationFactors"]["temperatureCalibrationOffset"]', None,               'float'),
        'humidityCalibrationFactor':    (1,                          '["calibrationFactors"]["humidityCalibrationFactor"]',    None,               'float'),
        'humidityCalibrationOffset':    (0,                          '["calibrationFactors"]["humidityCalibrationOffset"]',    None,               'float'),
        'pressureCalibrationFactor':    (1,                          '["calibrationFactors"]["pressureCalibrationFactor"]',    None,               'float'),
        'pressureCalibrationOffset':    (0,                          '["calibrationFactors"]["pressureCalibrationOffset"]',    None,               'float'),
        'pm10CalibrationFactor':        (1,                          '["calibrationFactors"]["pm10CalibrationFactor"]',        None,               'float'),
        'pm10CalibrationOffset':        (0,                          '["calibrationFactors"]["pm10CalibrationOffset"]',        None,               'float'),
        'pm25CalibrationFactor':        (1,                          '["calibrationFactors"]["pm25CalibrationFactor"]',        None,               'float'),
        'pm25CalibrationOffset':        (0,                          '["calibrationFactors"]["pm25CalibrationOffset"]',        None,               'float'),
        'pm1CalibrationFactor':         (1,                          '["calibrationFactors"]["pm1CalibrationFactor"]',         None,               'float'),
        'pm1CalibrationOffset':         (0,                          '["calibrationFactors"]["pm1CalibrationOffset"]',         None,               'float'),
        'sampleDuration':               (30,                         '["sampleDuration"]',                                     None,               'int'),
        'mqttPort':                     (1883,                       '["mqttPort"]',                                           None,               'int'),
        'mqttUrl':                      (base_url,                   '["mqttUrl"]',                                            None,               'str'),
        'ledStyle':                     (settings.led_style,         '["ledStyle"]',                                           'led_style',        'str'),
        'deviceToken':                  (settings.device_token,      '["deviceToken"]',                                        'device_token',     'str'),
        'localSsid':                    (device_name,                '["localSsid"]',                                          None,               'str'),
        'localPass':                    (settings.local_pass,        '["localPass"]',                                          'local_pass',       'str'),
        'wifiSsid':                     (settings.wifi_ssid,         '["wifiSsid"]',                                           'wifi_ssid',        'str'),
        'wifiPass':                     (settings.wifi_pass,         '["wifiPass"]',                                           'wifi_pass',        'str'),
        'serialNumber':                 (settings.birdhouse_number,  '["serialNumber"]',                                       'birdhouse_number', 'int'),
    }
def make_params(nums):
    mothership_url = birdhouse_utils.make_mothership_url(args)

    tbapi = TbApi(mothership_url, thingsboard_username, thingsboard_password)

    params = []

    for num in nums:
        print(f"Retrieving details for device {num}... ", end='', flush=True)
        device_name = birdhouse_utils.make_device_name(num)
        dash_name = birdhouse_utils.make_dash_name(num)

        device = tbapi.get_device_by_name(device_name)
        dash = tbapi.get_dashboard_by_name(dash_name)
        dash_url = tbapi.get_public_dash_url(dash)
        tiny_url = make_tiny_url(dash_url)

        if device is None:
            print(f"Failed.\nCould not find device {num}... Aborting.")
            exit()

        token = tbapi.get_device_token(device)

        params.append((
            birdhouse_utils.get_sensor_type(num)[1],
            birdhouse_utils.make_device_number(num),
            token,
            tiny_url
        ))
        print("done.")

    return params
def count_records(client, bhnums):
    device_names = [birdhouse_utils.make_device_name(n) for n in bhnums]

    comma = "','"
    command = f'{POSTGRES_COMMAND} "select device.name, count(*), min(ts), max(ts) from ts_kv join device on ts_kv.entity_id = device.id where entity_id in (select id from device where name in (\'{comma.join(device_names)}\')) group by device.name order by device.name"'
    log.info(f"Command: {command}")

    print(f"Counting records for {', '.join(device_names)}...", end='')
    out = run_command(client, command).strip().split("\n")
    print(" done.")

    stats = dict()
    log.info(f"Output: {out}")

    for o in out:
        if o.strip() == "":
            continue

        bhnum, count, min_ts, max_ts = o.split("|")
        stats[bhnum] = int(count), datetime.datetime.fromtimestamp(
            int(min_ts) / 1000), datetime.datetime.fromtimestamp(
                int(max_ts) / 1000)

    log.info(f"Returning: {stats}")
    return stats
Exemple #7
0
def get_or_validate_device_token(tbapi, birdhouse_number, token_to_validate, create_thingsboard_objects):
    # Ensure we have a valid device token, unless we don't know our birdhouse_number yet, in which case there's nothing we can do
    if birdhouse_number is None:
        return None

    device_name = birdhouse_utils.make_device_name(birdhouse_number)

    if token_to_validate is None:
        # Does this device already exist?
        device = tbapi.get_device_by_name(device_name)

        # Does device exist?
        if device is not None:
            print("Fetching device token...", end='')
            device_token = tbapi.get_device_token(device)
            print(" ok")
            return device_token

        # Device does not exist... should we create it?
        if create_thingsboard_objects:
            return create_server_objects(tbapi, birdhouse_number)   # Create the device and return its token; will fail if server objects exist

        return None

    else:
        print("Validating device token...", end='')
        if not validate_device_token(birdhouse_number, token_to_validate):
            print(" failed\nDevice token appears invalid for specified device. Please check the number and dial again.")
            exit()
        print(" ok")
        return token_to_validate
Exemple #8
0
def validate_device_token(birdhouse_number, token):
    if birdhouse_number is None or token is None:
        return False

    device_name = birdhouse_utils.make_device_name(birdhouse_number)

    # Return whether the device token is valid
    url = key_validation_url + "?name=" + device_name + "&key=" + token

    tries = 3

    while tries > 0:
        resp = requests.get(url)

        # Server should always return 200 regardless of whether the token is valid or not.
        if resp.status_code == 200:
            break

        print(resp)

        tries -= 1

    if tries == 0:
        print("\nError validating device token; server returned code " +
              str(resp.status_code))
        print("Aborting!")
        exit()

    if resp.text == 'bad_device':
        print("\nThe device number you specified is unknown or invalid.")
        print("Aborting!")
        exit()

    return resp.text == 'true'
def ensure_devices_exist(device_nums):
    """
    Ensure all devices we're going to process exist on both the source and destination machines
    """
    tbapi_old = TbApi(birdhouse_utils.make_mothership_url(old_server_ip),
                      thingsboard_username, thingsboard_password)
    tbapi_new = TbApi(birdhouse_utils.make_mothership_url(new_server_ip),
                      thingsboard_username, thingsboard_password)

    print(
        "Making sure every device we want to migrate exists on both source and desitnation machines"
    )

    for num in device_nums:
        print(".", end="")

        name = birdhouse_utils.make_device_name(num)

        old_device = tbapi_old.get_device_by_name(name)
        if old_device is None:
            print(f"\nDevice {name} does not exist on old server!")
            exit()

        new_device = tbapi_new.get_device_by_name(name)
        if new_device is None:
            print(f"\nDevice {name} does not exist on new server!")
            exit()

        old_key = tbapi_old.get_id(old_device)
        new_key = tbapi_new.get_id(new_device)

        if old_key != new_key:
            print("\nDevice keys are different on old and new servers!")
            exit()
    print()
Exemple #10
0
def main():
    tbapi = TbApi(motherShipUrl, username, password)

    # Lookup missing fields, such as zip, lat, and lon
    birdhouse_utils.update_customer_data(cust_info)

    if cust_info["lat"] is None or cust_info["lon"] is None:
        print("Must have valid lat/lon to continue!")
        exit(1)

    name = birdhouse_utils.make_device_name(birdhouse_number)

    cust = tbapi.get_customer(name)
    devices = tbapi.get_customer_devices(cust)

    print(devices)

    device = tbapi.get_device_by_name(name)

    customer = tbapi.update_customer(cust, None, cust_info["address"],
                                     cust_info["address2"], cust_info["city"],
                                     cust_info["state"], cust_info["zip"],
                                     cust_info["country"])
    server_attributes = {
        "latitude": cust_info["lat"],
        "longitude": cust_info["lon"],
        "address": birdhouse_utils.one_line_address(cust_info)
    }
    tbapi.set_server_attributes(device, server_attributes)

    exit()

    cust = tbapi.get_customer(name)
def doit(birdhouse_number):
    telemetry, reference_telemetry = retrieve_data(birdhouse_number)
    data_df = create_data_frame(telemetry, "data") 
    ref_df  = create_data_frame(reference_telemetry, "ref")

    # Combine our telemetry with the reference values into a single dataframe; average it to hourly periods; kick any periods where we're missing data
    merged = pd.merge_ordered(data_df, ref_df, on='ts', how='outer')
    merged.set_index('ts', inplace=True)
    merged.index = pd.to_datetime(merged.index)
    resampled = merged.resample('1H').mean()
    resampled.dropna(inplace=True) 


    ### Here we have two columns of aligned data (generally hourly, but could be other intervals) with missing values stripped out

    # Plot our original datasets
    plt.plot(resampled["ref"].values, label="deq ref")
    # plt.plot(resampled["data"].values, label="pms data")

    scaling_factor_based_on_rescaled_data = compute_scaling_factor(resampled["data"], resampled["ref"])
    # print("Scaling factor (resampled data)", scaling_factor_based_on_rescaled_data)

    scaling_factor_based_on_orig_data = compute_scaling_factor(data_df["data"], ref_df["ref"])
    # print("Scaling factor (orig data)", scaling_factor_based_on_orig_data)



    d_resampled = resampled["data"].values.reshape(-1, 1)
    r_resampled = resampled["ref"] .values.reshape(-1, 1)


    # Apply the correction factor derived from two different resolutions of our data in order to see which creates a better fit
    # with our reference data
    d_resampled_rescaled = d_resampled * scaling_factor_based_on_rescaled_data
    d_orig_rescaled      = d_resampled * scaling_factor_based_on_orig_data


    offset_rescaled = compute_offset(d_resampled_rescaled, r_resampled)
    offset_orig     = compute_offset(d_orig_rescaled,      r_resampled)




    # These are two candidates; both represent hourly data points.  Which fits better?
    d_resampled_rescaled_offset = d_resampled_rescaled + offset_rescaled
    d_orig_rescaled_offset      = d_orig_rescaled + offset_orig


    error_resampled_method = sklearn.metrics.r2_score(r_resampled, d_resampled_rescaled_offset)
    method1.append(error_resampled_method)
    # print("r^2 for dataset", birdhouse_number, "using resampled data method", error_resampled_method)  

    error_orig_method = sklearn.metrics.r2_score(r_resampled, d_orig_rescaled_offset)
    method2.append(error_orig_method)

    device_name = birdhouse_utils.make_device_name(birdhouse_number)


    print("Calibration factor/offset for device " + device_name + ":", scaling_factor_based_on_orig_data, offset_orig)
def print_item_counts(old_client, new_client, nums):
    print("Counting records for devies on old and new servers...")
    for num in nums:
        name = birdhouse_utils.make_device_name(num)
        cmd = f'{POSTGRES_COMMAND} "select count(*) from ts_kv where entity_id in (select id from device where name =\'{name}\');"'
        old_count = run_command(old_client, cmd).strip()
        new_count = run_command(new_client, cmd).strip()
        print(
            f"{name}: {'Same' if old_count == new_count else 'Different'} [Old | New: {old_count} | {new_count}]"
        )
Exemple #13
0
def update_dash_def(dash_def, customer_name, device_id):
    aliases = dash_def["configuration"]["entityAliases"].keys()
    for a in aliases:
        try:
            dash_def["configuration"]["entityAliases"][a][
                "alias"] = birdhouse_utils.make_device_name(birdhouse_number)
            if "singleEntity" in dash_def["configuration"]["entityAliases"][a][
                    "filter"]:
                dash_def["configuration"]["entityAliases"][a]["filter"][
                    "singleEntity"]["id"] = device_id
        except Exception as e:
            print(
                'Alias: %s\n dash_def["configuration"]["entityAliases"][a]["filter"]: %s'
                % (a, dash_def["configuration"]["entityAliases"][a]["filter"]))
            raise e
Exemple #14
0
def main():

    mothership_url = birdhouse_utils.make_mothership_url(args, config)
    tbapi = TbApi(mothership_url, thingsboard_username, thingsboard_password)

    for num in args["<num>"]:
        print(f"Retrieving details for device {num}... ", end='', flush=True)
        name = birdhouse_utils.make_device_name(num)
        device = tbapi.get_device_by_name(name)

        if device is None:
            print(f"Failed.\nCould not find device {num}... Aborting.")
            exit()

        token = tbapi.get_device_token(device)
        print("done.")
        print(token)
def retrieve_data(birdhouse_number):
    device_name = birdhouse_utils.make_device_name(birdhouse_number)
    
    if len(calibrationData[birdhouse_number]["attributes"]) == 0:
        print("Nothing to compare!")
        exit()

    start_ts = calibrationData[birdhouse_number]["periodStart"]
    end_ts   = calibrationData[birdhouse_number]["periodEnd"]
    reference_device_name = calibrationData[birdhouse_number]["referenceDevice"]

    attributes = []
    reference_attributes = []

    for a1, a2 in calibrationData[birdhouse_number]["attributes"].items():
        attributes.append(a1)
        reference_attributes.append(a2)


    device = tbapi.get_device_by_name(device_name)
    if device is None:
        print("Could not find device " + device_name)
        exit()
    reference_device = tbapi.get_device_by_name(reference_device_name)
    if reference_device is None:
        print("Could not find reference device " + reference_device_name)
        exit()
        # 004 005 003 010 002 011 012 013
    # for i in range(0, len(attributes)):
    #     telemetry = get_telemetry(device, attributes[i], start_ts, end_ts)[attributes[i]]
    #     reference_telemetry = get_telemetry(reference_device, reference_attributes[i], start_ts, end_ts)[reference_attributes[i]]

    #     print(telemetry)
    #     print(reference_telemetry)


    from testData import telemetry, reference_telemetry

    return telemetry[birdhouse_number], reference_telemetry[birdhouse_number]
def export_data(client, bhnum, filename):
    """
    Export data from postres server on the client to filename, in CSV format
    """
    device_name = birdhouse_utils.make_device_name(bhnum)

    command = f"""   {POSTGRES_COMMAND} "COPY (select {COLUMN_LIST} from ts_kv 
                                               where entity_id = (select id from device where name = \'{device_name}\'))
                                         TO \'{filename}\' (DELIMITER \',\');"    """

    print(f"Exporting data for {device_name} to {filename}...", end='')
    out = run_command(client, command)
    print(" done.")

    if out.strip() != "":
        print(out)
        exit()

    linect = run_command(client, f"wc -l {filename}|awk '{{print $1}}'")
    print(f"Exported {int(linect.strip()) - 1} records.")

    return filename
def verify_devices_remapped(device_nums,
                            min_interval=120,
                            age_considered_offline=7 * DAYS):  # In seconds
    """
    Look at the ages of the most recent telemetry, and ensure each device is sending current telemetry to the new server.
    The theory is that once a device is talking to the new server, it will never go back to the old, and we can safely
    shift all telemetry from the old server.

    min_interval is the minimum time, in seconds, that the new server must be ahead of the old server for this check to pass.

    Note that if the most recent telemetry on the old server is older than age_considered_offline, we'll assume the device is out of contact
    (perhaps disconnceted or off), and we'll go ahead and migrate the data over.
    """
    tbapi_old = TbApi(birdhouse_utils.make_mothership_url(old_server_ip),
                      thingsboard_username, thingsboard_password)
    tbapi_new = TbApi(birdhouse_utils.make_mothership_url(new_server_ip),
                      thingsboard_username, thingsboard_password)

    old_client = create_client(old_server_ip)
    new_client = create_client(new_server_ip)

    print(
        "Verifying devices have attached themselves to the new server and aren't still sending data to the old"
    )

    now = int(time.time() * 1000)

    for num in device_nums:
        print(".", end="")

        name = birdhouse_utils.make_device_name(num)
        latest_old = get_latest_telemetry_date(tbapi_old, old_client,
                                               name) or 0

        if latest_old == 0:  # There is no data on the old server; no need to migrate, but no problem moving forward, either
            continue

        latest_new = get_latest_telemetry_date(tbapi_new, new_client,
                                               name) or 0

        age_of_old = int(
            (now - latest_old) /
            1000)  # Age of most recent telemetry on old server in seconds

        diff = int(
            (latest_new - latest_old) / 1000
        )  # Diffrence in ages between most recent telmetry on new and old server, in seconds

        if age_of_old < age_considered_offline and diff < min_interval:
            print(
                f"\nIt looks like device {name} is still active and hasn't switched to new server yet.  Not ready to migrate data!"
            )
            print(
                f"\tLast telemetry on old server was {format_time_delta(age_of_old)} ago."
            )
            if latest_new == 0:
                print(
                    "\tThe device has not yet sent any data to the new server."
                )
            else:
                print(
                    f"\tLast telemetry on new server was {format_time_delta(now - latest_new)} ago."
                )
            exit()
    print()
Exemple #18
0
def upload(source_file, source_file_with_version, build_target, remote_dir,
           devices):

    if devices == "all":
        print("Uploading " + build_target + " for all devices to " +
              remote_dir)
        for output_line in execute('"' + winscp_program_location + '" "' +
                                   winscp_profile + '" /command "cd ' +
                                   remote_dir + '" "put ' + build_target +
                                   '" "exit"'):
            print(output_line, end="")
        return

    print("Uploading " + build_target + " for devices: " + devices)

    first = True

    device_list = devices.replace(" ", "").split(",")

    prepared_device_list = []
    # Expand any ranges (1-3 to 1,2,3)
    for num in device_list:
        if "-" in num:
            low, high = num.split("-")
            nums = list(
                range(int(low),
                      int(high) + 1)
            )  # + 1 to ensure we include the high value, which would normally get omitted because of list index semantics

            prepared_device_list.extend(nums)
        else:
            prepared_device_list.append(int(num))

    for num in list(set(prepared_device_list)):
        mac_address = None
        device_name = birdhouse_utils.make_device_name(num)
        device = tbapi.get_device_by_name(device_name)
        attrs = tbapi.get_client_attributes(device)
        for attr in attrs:
            if attr["key"] == "macAddress":
                mac_address = attr["value"]
                break

        if mac_address is None:
            print("Couldn't find MAC address for device " + device_name)
            exit()

        print("Uploading " + build_target + " for device " + device_name +
              " (MAC addr " + mac_address + ")")

        sanitized_device_name = device_name.replace(
            " ", "_")  # Strip spaces; makes life easier
        device_specific_remote_dir = remote_dir + "/" + sanitized_device_name + "_" + mac_address
        mkdir_command = 'call mkdir -p ' + device_specific_remote_dir

        if first:  # Upload a new file
            remote_source_dir = device_specific_remote_dir

            for output_line in execute('"' + winscp_program_location + '" "' +
                                       winscp_profile + '" /command "' +
                                       mkdir_command + '" "cd ' +
                                       device_specific_remote_dir + '" "put ' +
                                       build_target + '" "exit"'):
                print(output_line, end="")

            first = False

        else:  # Copy file we just uploaded, to reduce bandwidth and go faster
            cp_command = 'call cp ' + remote_source_dir + '/' + source_file_with_version + ' ' + device_specific_remote_dir + '/'

            for output_line in execute('"' + winscp_program_location + '" "' +
                                       winscp_profile + '" /command "' +
                                       mkdir_command + '" "' + cp_command +
                                       '" "exit"'):
                print(output_line, end="")
Exemple #19
0
def main(settings):
    print("Sensorbot Device Provisioning Script Version " + __version__)

    if upload_img or should_upload_firmware:
        settings.esp = find_birdhouse_port()
        if settings.esp is None:
            if ui_mode:
                start_ui_no_device()
            else:
                exit()

    if upload_img:
        if not os.path.isfile(firmware_image):
            print(f"Could not find firmware image {firmware_image}")
            print("Aborting.")
            exit()

        upload_firmware(print, settings.esp, firmware_image)
        exit()

    validate_led_style(settings.led_style)

    # Instantiate our API helper if needed
    if should_set_up_thingsboard:
        tbapi = TbApi(mothership_url, thingsboard_username,
                      thingsboard_password)

    if should_delete_only:
        birdhouse_utils.purge_server_objects_for_device(
            tbapi, settings.birdhouse_number)
        exit()

    device_name = birdhouse_utils.make_device_name(settings.birdhouse_number)
    if settings.birdhouse_number is not None:
        print("Configuring device '" + device_name + "'\n")

    # Get the port first to ensure our local house is in order before we validate things over the network
    validated_token = False
    if should_upload_firmware:
        if settings.birdhouse_number is not None and settings.device_token is not None:
            if not validate_device_token(settings.birdhouse_number,
                                         settings.device_token):
                print(
                    "Passed an invalid device token for the specified device.")
                print("Aborting.")
                exit()
            validated_token = True

    if should_create_thingsboard_objects:
        settings.device_token = create_server_objects(
            tbapi, settings.birdhouse_number
        )  # This will fail if server objects already exist

    if testmode:
        input("Press Enter to cleanup created objects...")
        settings.birdhouse_utils.purge_server_objects_for_device(
            tbapi, settings.birdhouse_number)
        exit()

    # assign_device_to_public_user(token, device_id)

    if ui_mode:
        start_ui(tbapi, settings.esp._port)
        exit()

    if not validated_token:
        settings.device_token = get_or_validate_device_token(
            tbapi, settings.birdhouse_number, settings.device_token,
            should_create_thingsboard_objects)

    if should_upload_firmware:
        upload_firmware_and_configure(print, settings)

    if attributes_only:
        set_params(print, settings)
Exemple #20
0
import sys
import os
import serial
import time
import json

from thingsboard_api_tools import TbApi  # sudo pip install git+git://github.com/eykamp/thingsboard_api_tools.git --upgrade

from config import motherShipUrl, username, password, dashboard_template_name, default_device_local_password, wifi_ssid, wifi_password, esptool_exe_location
firmware_folder_name = r"C:\Temp\BirdhouseFirmwareBuildFolder"

# This to be passed in
birdhouse_number = 6
led_style = 'RYG'  #  RYG, RYG_REVERSED, DOTSTAR, 4PIN, BUILTIN_ONLY, UNKNOWN

birdhouse_name = birdhouse_utils.make_device_name(birdhouse_number)
sensor_type = birdhouse_utils.get_sensor_type(birdhouse_number)

cust_info = {}

cust_info["name"] = birdhouse_name
cust_info["address"] = "2103 SE Tibbetts"
cust_info["address2"] = ""
cust_info["city"] = "Portland"
cust_info["state"] = "OR"
cust_info["zip"] = None  # Will be populated by geocoder if empty
cust_info["country"] = "USA"
cust_info["lat"] = None  # Will be populated by geocoder if empty
cust_info["lon"] = None  # Will be populated by geocoder if empty
cust_info["email"] = "*****@*****.**"
cust_info["phone"] = "555-1212"
Exemple #21
0
def create_device(cleanup):

    # Get a definition of our template dashboard
    template_dash = tbapi.get_dashboard_by_name(dashboard_template_name)
    if template_dash is None:
        print("Cannot retrieve template dash %s.  Is that the correct name?" %
              dashboard_template_name)
        sys.exit()

    dash_def = tbapi.get_dashboard_definition(tbapi.get_id(template_dash))

    customer = create_customer(cust_info)
    if customer is None:
        exit()

    server_attributes = {
        "latitude": cust_info["lat"],
        "longitude": cust_info["lon"],
        "address": birdhouse_utils.one_line_address(cust_info)
    }

    shared_attributes = {"LED": "Unknown"}

    device = tbapi.add_device(
        birdhouse_utils.make_device_name(birdhouse_number), sensor_type,
        shared_attributes, server_attributes)
    device_id = tbapi.get_id(device)

    # We need to store the device token as a server attribute so our REST services can get access to it
    device_token = tbapi.get_device_token(device_id)

    server_attributes = {"device_token": device_token}

    tbapi.set_server_attributes(device_id, server_attributes)

    try:
        # Upate the dash def. to point at the device we just created (modifies dash_def)
        update_dash_def(dash_def, cust_info["name"], device_id)
    except Exception as ex:
        print("Exception encountered: Cleaning up...")
        tbapi.delete_device(device_id)
        tbapi.delete_customer_by_id(tbapi.get_id(customer))
        raise ex

    # Create a new dash with our definition, and assign it to the new customer
    dash = tbapi.create_dashboard_for_customer(cust_info["name"] + ' Dash',
                                               dash_def)
    tbapi.assign_dash_to_user(tbapi.get_id(dash), tbapi.get_id(customer))

    print("Device token for " + birdhouse_name +
          " (set device token: setparams?deviceToken=" + device_token + ")")

    if cleanup:
        # input("Press Enter to continue...")   # Don't run from Sublime with this line enabled!!!

        print("Cleaning up! (device token rendered invalid)")
        tbapi.delete_dashboard(tbapi.get_id(dash))
        tbapi.delete_device(device_id)
        tbapi.delete_customer_by_id(tbapi.get_id(customer))

    return device_token