docs.unity3d.com
  • Manual
  • Scripting API
  • Changelog
  • License

    • Unity Live Systems Data
      • Installation
      • What's new
      • Upgrade guide
    • Get started
      • Take it further
    • Basic concepts
    • Configure your service
      • Add and configure user-supplied secrets
      • Associate 3D objects with source devices
      • Configure a facility device simulator
      • Configure data connectors
        • Device connectors
          • Azure IoT Hub device connector
          • Facility Simulator device connector
          • HTTP device connector
        • Telemetry connectors
          • Azure EventHub telemetry connector
    • Develop your application
      • Create environment settings
      • Create a services controller
      • Implement a telemetry history controller
    • Troubleshooting
    • Glossary
    • REST APIs

    Take it further

    After you Get started with Live Systems Data, use this section to learn more about the settings and components used in the sample project, which includes code snippets that you can use in future projects. By further investigating the sample project and its scripts, you learn how to do more with the Live Systems Data services.

    Environment settings

    You can find your EnvironmentSettings by going to the Services/Settings folder in your Samples directory.

    The sample uses default values for its environment settings. To use other data sources in the environment settings, select the EnvironmentSettings ScriptableObject and modify the fields displayed in the Inspector window.

    Services controller

    The Services GameObject makes up the foundation on which other services are built. The ServicesController component exists inside the Services GameObject.

    To open and edit the ServicesController script, right-click the ServicesController component and select Edit script. The script opens in the external script editor you have set in your Editor preferences.

    You can also find and open your ServicesController script by going to the Assets/Samples/Digital Twins Live SDK/<package-version>/How To Use Services/Controllers folder.

    For more details on the ServicesController script, see the Create a services controller page.

    Login controller

    The LoginController component authenticates and connects Live Systems Data services to one another.

    To access the LoginController script, go to Services and select the Login GameObject. Alternatively, you can find and open your LoginController script by going to the Assets/Samples/Digital Twins Live SDK/<package-version>/How To Use Services/Controllers folder.

    When you run a scene, the LoginController script confirms authentication and connection through console logs and a public Access Token field in the Inspector window when you select the GameObject.

    Login controller initialization

    The LoginController script implements the MonoBehaviour.Start() to initialize the login controller. The initialization script also does the following:

    • Implements an async method to wait for the result of calls to the Authenticator.
    • References the ServicesController to assign a listener to the Authenticator.AuthenticationStateChanged event.
    • Implements an InitializeAsync method to initialize the Authenticator.
    • Confirms the AuthenticationState.
    • Calls LoginAsync() to continue the login flow.
    async void Start()
    {
        m_ServicesController.Authenticator.AuthenticationStateChanged += OnAuthenticationStateChanged;
    
        await m_ServicesController.Authenticator.InitializeAsync();
    
        if (m_ServicesController.Authenticator.AuthenticationState == AuthenticationState.LoggedOut)
        await m_ServicesController.Authenticator.LoginAsync();
    }
    

    Logged in state

    After the Authenticator updates its AuthenticationState, the LoginController script calls the AuthenticationStateChanged event. The OnAuthenticationStateChanged listener receives this event.

    All states are logged to the console, but only the LoggedIn state also launches the task FetchUserInfoAccessToken.

    void OnAuthenticationStateChanged(AuthenticationState state)
    {
        switch (state)
        {
            case AuthenticationState.LoggedOut:
                Debug.Log("User logged out.");
                break;
    
            case AuthenticationState.LoggedIn:
                Debug.Log("User logged in.");
                Task.Run(FetchUserInfoAndAccessToken);
                break;
    
            case AuthenticationState.AwaitingLogin:
                Debug.Log("Awaiting login...");
                break;
    
            case AuthenticationState.AwaitingLogout:
                Debug.Log("Awaiting logout...");
                break;
        }
    

    Facility service connection

    The LoginController script implements the MonoBehaviour.Start() to initialize the login controller. The initialization script also implements an async method to wait for the result of calls to the Authenticator.

    After the Authenticator logs you in, you can get an access token and connect to the FacilityService. The facility service script does the following:

    • Obtains valid UserInfo through UserInfoProvider.GetUserInfoAsync().
    • Obtains a valid string representing the Access Token through Authenticator.GetAccessTokenAsync().
    • Uses the string to populate the public field m_AccessToken for visibility in the Inspector window.
    • Retrieves a list of available scenes through SceneProvider.ListScenesAsync. This Scene definition exists within the Unity.Cloud.Common namespace and is different from the Unity Editor definition of a scene.
    • Iterates the list of scenes to retrieve a scene that matches the WorkspaceId and FacilityId from your EnvironmentSettings. If there isn't a match, it logs a warning to your console.
    • Provides scene, userInfo, and accessToken and establishes a connection through the FacilityService.ConnectAsync(scene, userInfo, accessToken).
    async void FetchUserInfoAndAccessToken()
    {
        var userInfo = await m_ServicesController.UserInfoProvider.GetUserInfoAsync();
        var accessToken = await m_ServicesController.Authenticator.GetAccessTokenAsync();
        m_AccessToken = accessToken;
    
        var sceneList = await m_ServicesController.SceneProvider.ListScenesAsync();
    
        var scene = sceneList
            .FirstOrDefault(scene =>
                scene.WorkspaceId.ToString().Equals(m_ServicesController.EnvironmentSettings.WorkspaceId) &&
                scene.Id.ToString().Equals(m_ServicesController.EnvironmentSettings.FacilityId));
    
        if (scene is null)
        {
            Debug.LogWarning($"No {nameof(scene)} found in DT Portal for Facility: " +
                $"{m_ServicesController.EnvironmentSettings.FacilityId} and Workspace: " +
                $"{m_ServicesController.EnvironmentSettings.WorkspaceId}. If given Facility exists " +
                $"in LSD, only LSD services will work.");
        }
    
        await m_ServicesController.FacilityService.ConnectAsync(scene, userInfo, accessToken);
    }
    

    Configuration controller

    To access the ConfigurationController script, go to the Assets/Samples/Digital Twins Live SDK/<package-version>/How To Use Services/Controllers folder.

    Configuration controller behavior

    The ConfigurationController is made up of a single GetResultsAsync() method. To trigger this method, select Use Service in the Inspector window.

    Note: The ConfigurationControllerEditor script (Assets/Samples/Digital Twins Live SDK/<package-version>/How To Use Services/Editor/ConfigurationControllerEditor) takes information from the Use Service button and links it to the GetResultsAsync() method.

    The configuration controller script does the following:

    • Verifies the reference to the ServicesController.
    • Retrieves the ConfigurationService and stores it in the m_ConfigurationService variable. Any requests you make to the DeviceSummary and TimeSeriesPlotConfiguration use this service.
    • Calls GetDeviceSummaryAsync(m_DeviceType) with a valid string for m_DeviceType.
    • Uses the DeviceSummary to populate DeviceSummaryResults, if available.
    • Calls GetTimeSeriesPlotAsync(m_TelemetryKey) with a valid string for m_TelemetryKey.
    • Populates the TimeSeriesPlotMessage with a confirmation message if a TimeSeriesPlotConfiguration is returned.
    public async Task GetResultsAsync()
    {
        if (m_ServicesController is null)
        {
            Debug.LogError($"{nameof(m_ServicesController)} is not set.");
            return;
        }
    
        m_ConfigurationService ??= m_ServicesController.ConfigurationService;
        var deviceSummary = await m_ConfigurationService.GetDeviceSummaryAsync(m_DeviceType);
        if (deviceSummary is null)
        {
            Debug.Log($"No device summary for {m_DeviceType} was found.");
        }
        else
        {
            m_Result.DeviceSummaryResults.Add(new DeviceSummaryResult
            {
                PropertyNames = deviceSummary.PropertyNames?.ToList(),
                TelemetryNames = deviceSummary.TelemetryNames?.ToList()
            });
            Debug.Log($"The device summary for {m_DeviceType} was added to {nameof(m_Result)}.");
        }
    
        var timeSeriesPlot = await m_ConfigurationService.GetTimeSeriesPlotAsync(m_TelemetryKey);
        if (timeSeriesPlot is null)
        {
            Debug.Log($"No time series plot for {m_TelemetryKey} was found.");
        }
        else
        {
            m_Result.TimeSeriesPlotMessage.Add($"We found a time series plot for {m_TelemetryKey}!");
            Debug.Log($"The time series plot for {m_TelemetryKey} was added to {nameof(m_Result)}.");
        }
    }
    

    Device service

    The DeviceService component is shown through the DeviceController script. It retrieves all instances of LiveDevice from the data source.

    To access the DeviceController script, go to the Assets/Samples/Digital Twins Live SDK/<package-version>/How To Use Services/Controllers folder.

    Device service initialization

    The DeviceController script implements the MonoBehaviour.Start() to retrieve the DeviceService from the ServicesController.

    void Start()
    {
        m_DeviceService = m_ServicesController.DeviceService;
    }
    

    Device service behavior

    The GetResultsAsync() method shows the main behavior of the DeviceService component. To trigger this method, select Use Service in the Inspector window.

    Note: The DeviceControllerEditor script (Assets/Samples/Digital Twins Live SDK/<package-version>/How To Use Services/Editor/DeviceControllerEditor) takes information from the Use Service button and links it to the GetResultsAsync() method.

    The device controller script does the following:

    • Uses m_DeviceService.GetDevicesAsync() to retrieve the latest list of Live Devices from the data source.
    • Selects the first Live Device and associates it with the scene's DeviceGameObject through its liveDevice.GameObject assignment, and is selected through setting the liveDevice.IsSelected boolean to true.
    • Calls m_DeviceService.GetCachedDevices() to prepare the LiveDeviceResultView for each LiveDevice. This array populates the Results > Live Devices field in the Inspector window.
    • Uses m_DeviceService.GetSelectedLiveDevices to isolate each LiveDevice that has an IsSelected boolean set to true. This collection populates the Results > Selected Live Devices field in the Inspector window.
    public async Task GetResultsAsync()
    {
        var liveDevices = await m_DeviceService.GetDevicesAsync();
        var liveDevice = liveDevices.FirstOrDefault();
    
        if (liveDevice != null)
        {
            liveDevice.GameObjects?.AddRange(m_DeviceGameObjects);
            liveDevice.IsSelected = true;
        }
    
        m_Result.LiveDevices = m_DeviceService
            .GetCachedDevices()
            .Select(device => new LiveDeviceResultView(device))
            .ToArray();
        m_Result.SelectedLiveDevices = m_DeviceService
            .GetSelectedLiveDevices()
            .Select(device => new LiveDeviceResultView(device))
            .ToArray();
    }
    

    Notification service

    The NotificationService component is shown through the NotificationController script. It posts and receives a mock NotificationResource.

    To access the NotificationController script, go to the Assets/Samples/Digital Twins Live SDK/<package-version>/How To Use Services/Controllers folder.

    Notification service initialization

    The NotificationController script implements the MonoBehaviour.Start() to retrieve the NotificationService and DeviceService from the ServicesController.

    void Start()
    {
        m_NotificationService = m_ServicesController.NotificationService;
        m_DeviceService = m_ServicesController.DeviceService;
    }
    

    Notification service behavior

    The GetResultsAsync() method sends a mock NotificationResource with SendNotificationAsync(), and retrieves the result using m_NotificationService.GetNotifications(). To trigger this method, select Use Service in the Inspector window.

    Note: The NotificationControllerEditor script (Assets/Samples/Digital Twins Live SDK/<package-version>/How To Use Services/Editor/NotificationControllerEditor) takes information from the Use Service button and links it to the GetResultsAsync() method.

    The notification controller script does the following:

    • Uses m_DeviceService.GetDevicesAsync() to retrieve the latest list of Live Devices from the data source.
    • Selects the first Live Device and uses its Device.Id string to create a valid NotificationRequestResource.
    • Adds the new NotificationRequestResource to a List to match the expected parameter for m_NotificationService.CreateNotificationsAsync(IEnumerable<NotificationRequestResource> notificationResources).
    • Uses m_NotificationService to create and post a NotificationResource and logs the results to the console.
    public async Task GetResultsAsync()
    {
        await SendNotificationAsync();
    
        m_Result.LatestNotifications = m_NotificationService
            .GetNotifications()
            .Select(notification => $"{notification.Timestamp}: {notification.Title}")
            .ToArray();
    }
    

    SendNotificationAsync() and AnyNotificationRequestResource(IEnumerable<string> deviceIdList) create and post a mock Notification.

    async Task SendNotificationAsync()
    {
        var liveDevices = await m_DeviceService.GetDevicesAsync();
        var liveDevice = liveDevices.FirstOrDefault();
    
        if (liveDevice is null || string.IsNullOrEmpty(liveDevice.Device.Id))
        {
            Debug.LogError($"There must be a {nameof(liveDevice.Device)} with correct id to successfully send a Notification.");
            return;
        }
    
        var notification = AnyNotificationRequestResource(new List<string>
        {
            liveDevice.Device.Id
        });
    
        var response = await m_NotificationService.CreateNotificationsAsync(new List<NotificationRequestResource> { notification });
    
        if (response.IsPresent())
        {
            Debug.Log("Notification created");
        }
        else
        {
            var json = JsonConvert.SerializeObject(notification);
            Debug.LogWarning($"Notification creation failed:\n{json}");
        }
    }
    
    static NotificationRequestResource AnyNotificationRequestResource(IEnumerable<string> deviceIdList)
        => new()
        {
            Title = $"Samples Title: {Guid.NewGuid().ToString()}",
            Message = $"Samples Message: {Guid.NewGuid().ToString()}",
            DeviceIds = deviceIdList,
            Timestamp = DateTimeOffset.UtcNow,
            Severity = "LOW"
        };
    

    Facility service

    The FacilityService component is shown through the FacilityController script. It retrieves available Facility information from the data source.

    To access the FacilityController script, go to the Assets/Samples/Digital Twins Live SDK/<package-version>/How To Use Services/Controllers folder.

    Facility service initialization

    The FacilityController script implements the MonoBehaviour.Start() to retrieve the FacilityService from the ServicesController.

    void Start()
    {
        m_FacilityService = m_ServicesController.FacilityService;
    }
    

    Facility service behavior

    The GetResultsAsync() method receives the FacilityInfo fields from the FacilityService. The FacilityInfo fields are the following:

    • IsLoggedIn
    • IsConnectedToMessagingService
    • WorkspaceId
    • FacilityId
    public void GetResults()
    {
        var facilityInfo = m_FacilityService.GetFacilityInfo();
        m_Result.IsLoggedIn = facilityInfo.IsLoggedIn;
        m_Result.IsConnectedToMessagingService = facilityInfo.IsConnectedToMessagingService;
        m_Result.WorkspaceId = facilityInfo.WorkspaceId;
        m_Result.FacilityId = facilityInfo.FacilityId;
    }
    

    Telemetry history service

    Important: The Telemetry history service isn't currently supported.

    The TelemetryHistoryService component is shown through the TelemetryHistoryController script. It retrieves the telemetry history based on a specific set of parameters.

    To access the TelemetryHistoryController script, go to the Assets/Samples/Digital Twins Live SDK/<package-version>/How To Use Services/Controllers folder.

    Telemetry history service initialization

    The TelemetryHistoryController script implements the MonoBehaviour.Start() to retrieve the TelemetryHistoryService and DeviceService from the ServicesController.

    void Start()
    {
        m_TelemetryHistoryService = m_ServicesController.TelemetryHistoryService;
        m_DeviceService = m_ServicesController.DeviceService;
    }
    

    Telemetry history service behavior

    The GetResultsAsync() method uses TelemetryHistoryService to retrieve a list of TelemetryHistory based on a specific set of parameters. The parameters are the following:

    • IEnumerable<string> deviceIds: identifies any Live Devices to be returned in TelemetryHistory.
    • string telemetryKey: the name of a single Telemetry specific to your data source. In this sample, that name is WindSpeed.
    • DateTimeOffset startTime: the earliest Timestamp on Telemetry included in the response.
    • DateTimeOffset endTime: the latest Timestamp on Telemetry included in the response.
    • int stepResolutionInSeconds: the frequency of results included in the response.

    The telemetry history controller script does the following:

    • Uses m_DeviceService.GetDevicesAsync() to retrieve the latest list of Live Devices from the data source.
    • Selects the first Live Device and uses its Device.Id string to create a request for TelemetryHistory. At least one valid Device.Id is required to request the TelemetryHistory successfully.
    • Defines the remaining parameters required to request the TelemetryHistory.
    • Calls the m_TelemetryHistoryService.GetHistoryAsync with the defined parameters to retrieve the TelemetryHistory that matches the request.
    • Formats the content of the response and displays it in the Result field in the Inspector window.
    public async Task GetResultsAsync()
    {
        var liveDevices = await m_DeviceService.GetDevicesAsync();
        var liveDevice = liveDevices.FirstOrDefault();
    
        if (liveDevice is null)
        {
            Debug.LogError($"There must be a {nameof(liveDevice)} to successfully receive Telemetry.");
            return;
        }
    
        m_Result.TelemetryHistoriesCount = 0;
    
        var endTime = DateTimeOffset.UtcNow;
        var startTime = endTime.AddMinutes(-10);
        var stepResolutionInSeconds = 1;
        var telemetryHistories = await m_TelemetryHistoryService.GetHistoryAsync(
            new[] { liveDevice.Device.Id },
            m_TelemetryKey,
            startTime,
            endTime,
            stepResolutionInSeconds);
    
        var telemetries = telemetryHistories
            .First()
            .Telemetries
            .First(group => group.Key.Equals(m_TelemetryKey))
            .ToList();
    
        m_Result.DeviceId = liveDevice.Device.Id;
        m_Result.TelemetryHistoriesCount = telemetries.Count;
    }
    
    Back to top Generated by DocFX
    Copyright © 2023 Unity Technologies — Terms of use
    • Legal
    • Privacy Policy
    • Cookies
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)
    "Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
    Generated by DocFX on 18 October 2023