Announcements

The Autodesk Community Forums has a new look. Read more about what's changed on the Community Announcements board.

Connection to PowerBI from Fusion manage

b_sugumar
Contributor

Connection to PowerBI from Fusion manage

b_sugumar
Contributor
Contributor

We want to create more customized reports using Power BI. Is there a way to connect PLM reports with Power BI?

0 Likes
Reply
902 Views
7 Replies
Replies (7)

tony.mandatori
Autodesk
Autodesk

You can create an R data source in Power BI and then use R code to retrieve the data from Fusion Manage. 

 

We have examples of this where all the records from each of the workspaces are retrieved and cached in PowerBI. PowerBI then refreshes the data source as needed. You can control which attributes that are cached by configuring workspace views for retrieving data. 

 

You will need PowerBI Desktop to configure the data source, and I would recommend the R-Studio IDE to test and debug the code. Sample code was posted in this forum, but I can post it again if needed.

b_sugumar
Contributor
Contributor

@tony.mandatori  could you please post the sample code? Thank you!

0 Likes

tony.mandatori
Autodesk
Autodesk

Here is the sample code. It uses the latest V2 APS Authentication.

 

You will need to do the following:

  1. Create an APS App at aps.autodesk.com
  2. Allow the client id in the General Settings of Fusion Manage.
  3. Update the template below to include, ClientID, ClientSecret, User ID and Tenant.

 

#######################################################################

#####################################################################
# Load libraries required for the R script
library(httr)
library(jsonlite)

clientid <- ""
clientsecret <- ""
userid <- ""
tenant <- ""

flcURL <- paste ("https://", tenant, sep="")
flcURL <- paste (flcURL, ".autodeskplm360.net", sep="")

# concatenate clientid and clientsecret strings using : separator
APP_Base64_String = paste(clientid, clientsecret, sep = ":")

# base64encode the string
Basic_App_Token <- base64_enc(APP_Base64_String)

# FLC Variables
FLC_Tenant_ID <- flcURL
X_user_id_Token <- userid
X_Tenant_Token <- tenant

# Other Variables
w_Offset <- 0
w_limit <- 999

App_Authenticate <-
  POST(
    'https://developer.api.autodesk.com/authentication/v2/token',
    add_headers(
      'Content-Type' = 'application/x-www-form-urlencoded',
      Authorization = paste("Basic", Basic_App_Token),
      Accept = 'application/json'
    ),
    body = I(
      list("grant_type" = "client_credentials",
           "scope" = "data:read")
    ),
    encode = "form"
  )
Access_Token <-
  paste("Bearer", content(App_Authenticate)$access_token, sep = " ")

print(paste("Basic", Basic_App_Token))


# a list of workspaces.
Get_Workspaces_URL <-
  paste(FLC_Tenant_ID,
        "/api/v3/workspaces?offset=",
        w_Offset,
        "&limit=",
        w_limit,
        "&",
        sep = "")

# print (Get_Workspaces_URL)

Get_Workspaces_Request <- GET(Get_Workspaces_URL,
                              add_headers(
                                .headers = c(
                                  "X-user-id" = X_user_id_Token,
                                  "X-Tenant" = X_Tenant_Token,
                                  "Authorization" = Access_Token
                                )
                              ))
Get_Workspaces_Data <-
  jsonlite::fromJSON(content(Get_Workspaces_Request, "text", "application/json", "UTF-8"))
Workspace_List <- flatten(data.frame(Get_Workspaces_Data))

# print(Workspace_List)

Parse_Workspace <-
  function(workspace_name,
           workspace_link,
           flag_latest,
           i_offset,
           i_limit) {
    Get_Tableaus_URL <- paste(FLC_Tenant_ID,
                              workspace_link,
                              "/tableaus",
                              sep = "")
    
    Get_Tableaus_Request <- GET(Get_Tableaus_URL,
                                add_headers(
                                  .headers = c(
                                    "X-user-id" = X_user_id_Token,
                                    "X-Tenant" = X_Tenant_Token,
                                    "Authorization" = Access_Token
                                  )
                                ))
    Get_Tab_Data <-
      jsonlite::fromJSON(content(Get_Tableaus_Request, "text", "application/json", "UTF-8"))
    Tab_List <- flatten(data.frame(Get_Tab_Data))
    
    tablink <- Tab_List[1, "tableaus.link"]
    tabname <- Tab_List[1, "tableaus.title"]
    
    Get_Items_URL <- paste(FLC_Tenant_ID,
                           tablink,
                           "?page=1&size=1200",
                           sep = "")
    
    print(Get_Items_URL)
    
    tryCatch({
      Get_Items_Request <- GET(Get_Items_URL,
                               add_headers(
                                 .headers = c(
                                   "X-user-id" = X_user_id_Token,
                                   "X-Tenant" = X_Tenant_Token,
                                   "Authorization" = Access_Token
                                 )
                               ))
      
      stop_for_status(Get_Items_Request)
    },
    http_error = function(e) {
      ## log error or otherwise recover
      print(e)
    })
    
    Get_Items_Data <-
      jsonlite::fromJSON(content(Get_Items_Request, "text", "application/json", "UTF-8"))

    X <- flatten((data.frame(Get_Items_Data)))
    
    Z <- data.frame(
      Date = as.Date(character()),
      File = character(),
      User = character(),
      stringsAsFactors = FALSE
    )
    
    for (row in 1:nrow(X)) {
      # print(row)
      
      rsname <- paste(wsname, tabname, "attributes", sep = "-")
      Y <- do.call(rbind.data.frame, X[row, "items.fields"])
      
      keeps <- c("id", "value")
      Y <- Y[keeps]
      
      tY <- setNames(data.frame(t(Y[,-1])), Y[, 1])
      Z <- rbind(Z, tY)
    }
    
    X <- cbind(X, Z)
    
    # Rename
    assign((paste(wsname, tabname, sep = "-")),
           X,
           envir = .GlobalEnv)
  }

for (row in 1:nrow(Workspace_List)) {
  wslink <- Workspace_List[row, "items.link"]
  wsname <- Workspace_List[row, "items.title"]
  
  tryCatch({
    print(paste("Name:", wsname,
                "Link:", wslink))
    
    Parse_Workspace(wsname, wslink, "true", 0, 10)
  },
  error = function(e) {
    cat("An error occurred:", conditionMessage(e), "\n")
    return(NA)  # Return NA in case of an error
  })
}

# Clear Variables
rm(
  clientid,
  clientsecret,
  userid,
  tenant,
  flcURL,
  APP_Base64_String,
  Basic_App_Token,
  FLC_Tenant_ID,
  X_user_id_Token,
  X_Tenant_Token,
  App_Authenticate,
  Access_Token,
  Get_Workspaces_URL,
  Get_Workspaces_Request,
  Get_Workspaces_Data
)

 

sven.dickmans
Autodesk
Autodesk

@b_sugumar A connection of PLM and PowerBI also can be created by using MS PowerAutomate only. In the example flow shown below, PowerAutomate will extract PLM data by using a defined PLM report and store the results in an Excel file. The given Excel file is driving a PowerBI report which gets refreshed at the end.

 

Similar to the solution using R shared by Tony, you will need an APS application to authenticate these requests using the API. You can change this flow to use the /tableaus endpoint instead of a PLM report also.

This flow may be easier to setup as it does not require any coding - and you can also use the same data for other automations in PowerAutomat (ie. send a post to a channel). Oh the flip side, this approach is less dynamic and requires some rework if your schema or PowerBI report source changes.

 

If this is an option for you, I can provide more details about the flow setup.

 

Screenshot 2024-09-16 at 10.30.21.png

b_sugumar
Contributor
Contributor

@sven.dickmans I would try this approach. It would be helpful if you share more detail.

Thank you!

0 Likes

sven.dickmans
Autodesk
Autodesk

@b_sugumar I will create the given instructions and share them in this post when ready (any time this week)

sven.dickmans
Autodesk
Autodesk

@b_sugumar Please find the setup instructions for the connection of Fusion Manage with Power BI using Power Automate attached. I took longer to document these steps as the initial setup requires a couple of steps. As a benefit, once you have the initial flow set up, you can use all Power Automate's capabilities with PLM. For example, you can automatically post messages to Teams or send mails with PLM data and events (i.e. a daily reports about latest approvals).