def create_devices_and_find_endpoints(stations):
    '''
    Creates all stations that currently do not exist in the IoT Hub as new devices. 
    Adds 'hub_endpoint' attribute to all stations (no matter whether it already exists in the hub or not)
    which can be used to send messages to the stations
    '''
    # TODO: make create_and_get_devices indepentent of stations to allow reusing it in other iot use cases
    connection_string = os.getenv("IOT_HUB_CONNECTION_STRING")
    host = os.getenv("IOT_HUB_HOSTNAME")

    try:
        iot_manager = IoTHubRegistryManager(connection_string)
        # note that 'get_devices() only works for cnt of devices <= 1000,
        # otherwise querying keys is more complex AND time consuming
        dev_list = iot_manager.get_devices()
        # convert list to dict for easy access
        devices = {
            dev_list[i].device_id: dev_list[i]
            for i in range(0, len(dev_list))
        }
        del dev_list

        new_devices = []

        for station in stations.values():
            device_name = station.get('station_name',
                                      station.get('station_id', ''))
            device = devices.get(device_name, None)

            if device != None:
                # if device already exists, only add its endpoint to the station
                station['hub_endpoint'] = get_endpoint_uri(
                    host, device_name,
                    device.authentication.symmetric_key.primary_key)
            else:
                # otherwise create device object and add its endpoint to station
                # the actual creation of the device in the hub happens at the end in a bulk
                new_device, new_endpoint = create_device(device_name, host)
                station['hub_endpoint'] = new_endpoint
                new_devices.append(new_device)

        # splitting operations in chunks prevents to large messages
        # that raise exceptions
        insert_chunks = chunks(new_devices, __CHUNK_SIZE)
        for chunk in insert_chunks:
            iot_manager.bulk_create_or_update_devices(chunk)
    except Exception as ex:
        print("Unexpected error {0}".format(ex))
def delete_all_devices():
    '''
    Deletes all devices in the Azure IoT Hub. This function is not
    used in the Azure Function but can be useful, if you want to reset
    the Azure Environment. 
    '''
    connection_string = os.getenv("IOT_HUB_CONNECTION_STRING")
    iot_manager = IoTHubRegistryManager(connection_string)
    dev_list = iot_manager.get_devices()
    delete_list = []
    for d in dev_list:
        dev = ExportImportDevice(id=d.device_id)
        dev.import_mode = "delete"
        delete_list.append(dev)

    # splitting operations in chunks prevents to large messages
    # that raise exceptions
    del_chunks = chunks(delete_list, __CHUNK_SIZE)
    for chunk in del_chunks:
        iot_manager.bulk_create_or_update_devices(chunk)
    replaced_twin = iothub_registry_manager.replace_twin(device_id, new_twin)
    print(replaced_twin)
    print("")

    # Update twin
    twin_patch = Twin()
    twin_patch.properties = TwinProperties(desired={"telemetryInterval": 3000})
    updated_twin = iothub_registry_manager.update_twin(device_id, twin_patch,
                                                       twin.etag)
    print(updated_twin)
    print("The twin patch has been successfully applied")

    # Get devices
    max_number_of_devices = 10
    devices = iothub_registry_manager.get_devices(max_number_of_devices)
    if devices:
        x = 0
        for d in devices:
            print_device_info("Get devices {0}".format(x), d)
            x += 1
    else:
        print("No device found")

    # Delete the device
    iothub_registry_manager.delete_device(device_id)

    print("GetServiceStatistics")
    registry_statistics = iothub_registry_manager.get_service_statistics()
    print(registry_statistics)