Get-VEDiagnostics.ps1

function Get-VEDiagnostics {
    <#
        .SYNOPSIS
            Return diagnostic data from a site
        .DESCRIPTION
            Return diagnostic data from a site
        .INPUTS
            The VE site object can be piped to the function
        .EXAMPLE
            $VESite | Get-VEDiagnostics
            Example of how to get diagnostic data from a site using the VRM API
        .NOTES
            Author: Decembry Quentin
    #>

    [CmdletBinding(DefaultParameterSetName='Object')]
    [OutputType([PSCustomObject])]
    [Alias()]
    param(
        # The VE session
        # Default: the default VE session
        [Parameter(Mandatory=$false)] [PSTypeName('VictronEnergy.Session')] $Session = $Script:VE_Session,
        
        # The VE site
        [Parameter(Mandatory=$true,ValueFromPipeline=$true,ParameterSetName='Object')] [PSTypeName('VictronEnergy.Site')] $Site,
        
        # The VE site id
        [Parameter(Mandatory=$true,ParameterSetName='Property')] [String] $SiteId,
        
        # Specifies the maximum number of returned records
        # Default: 1000
        [Parameter(Mandatory=$false)] [UInt16] $Count = 1000,
        
        # Switch to return only the unconfigured devices
        [Parameter(Mandatory=$false)] [Switch] $UnconfiguredDevices
    )

    begin {
        if ($PSBoundParameters['Debug']) {
            $DebugPreference = 'Continue'
        }
        
        if ($MyInvocation.MyCommand.ModuleName) { 
            $Private:ThisFunction = '{0}::{1}' -f $MyInvocation.MyCommand.ModuleName, $MyInvocation.MyCommand.Name
        } else {
            $Private:ThisFunction = '{0}::{1}' -f (Get-PSCallStack)[0].ScriptName, $MyInvocation.MyCommand.Name
        }
        
        Write-Debug "[$Private:ThisFunction] Begin"
    }
    
    process {
        Write-Debug "[$Private:ThisFunction] Process"

        switch ($PSCmdlet.ParameterSetName) {
            'Object' {
                $SiteId = $Site.IdSite
            }
            'Property' {
                # Nothing
            }
            default {
                thrown "Unsupported parameter set name '$_'"
            }
        }
        
        if (!$Session.Token) {
            throw 'Unable to list devices without a session token'
        }
        
        if (!$SiteId) {
            throw 'Unable to list devices without a site id'
        }
        
        $Uri = $Script:VE_VrmApiBaseUri + ('installations/{0}/diagnostics?count={1}' -f $SiteId, $Count)
        $Headers = @{ 'X-Authorization' = 'Bearer {0}' -f $Session.Token }
        
        try {
            Write-Debug "[$Private:ThisFunction] Send request to '$Uri'"
            $WebRequest = Invoke-WebRequest -UseBasicParsing -Uri $Uri -Method GET -Headers $Headers -ErrorAction Stop
            $Json = ConvertFrom-Json -InputObject $WebRequest.Content -ErrorAction Stop
            
            Write-Debug "[$Private:ThisFunction] Response validation"
            if ($Json.success -isnot [Boolean]) {
                throw "Invalid content received from server"
            }
            
            if (!$Json.success) {
                throw "Error occured"
            }
            
            Write-Debug "[$Private:ThisFunction] Processing records"
            foreach ($Record in $Json.Records) {
                Write-Debug "[$Private:ThisFunction] Record validation"
                if (!$Record.Device) {
                    Write-Error "Unexpected record (missing device)"
                }
                
                if (![Int]::TryParse($Record.Instance, [Ref]0)) {
                    Write-Error "Unexpected record (missing instance)"
                }
                
                if (!$Record.Timestamp) {
                    Write-Error "Unexpected record (missing timestamp)"
                }
                
                if (!$Record.Code) {
                    Write-Error "Unexpected record (missing code)"
                }
                
                Write-Debug "[$Private:ThisFunction] Create diagnostic object from record"
                $Hashtable = ConvertTo-Hashtable -InputObject $Record
                $Hashtable.PSTypeName = 'VictronEnergy.Diagnostic'
                $VEObject = [PSCustomObject] $Hashtable
                
                if ($Script:VE_ValueFormatting.$SiteId.([string]$VEObject.Code).Source -ne 'Diagnostic') {
                    try {
                        Write-Debug "[$Private:ThisFunction] Create value formatting object from diagnostic object"
                        $VEObject | Set-VEValueFormatting -ErrorAction SilentlyContinue
                    } catch {
                        $_ | ForEach-Object {
                            Write-Warning "[$Private:ThisFunction] $_"
                        }
                    }
                }
                
                Write-Debug "[$Private:ThisFunction] Return diagnostic object"
                Write-Output -NoEnumerate -InputObject $VEObject
            }
        } catch {
            $_ | ForEach-Object {
                Write-Error $_
            }
        }
    }
    
    end {
        Write-Debug "[$Private:ThisFunction] End"
    }
}

# SIG # Begin signature block
# MIIIbQYJKoZIhvcNAQcCoIIIXjCCCFoCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUKT9nvGogHMQ2AcEQlSxdv+du
# TN2gggX4MIICYjCCAgigAwIBAgITXwAAAAITcsrrTJecaQAAAAAAAjAKBggqhkjO
# PQQDAjAkMQswCQYDVQQGEwJCRTEVMBMGA1UEAxMMSG9tZSBSb290IENBMB4XDTIy
# MDUwNTE0MDMxOFoXDTMyMDUwNTE0MTMxOFowJzELMAkGA1UEBhMCQkUxGDAWBgNV
# BAMTD0hvbWUgSXNzdWluZyBDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDOT
# aIIU+QU7LfsmyPqGkCf53SrJuaBPpb5iVILCvG3cQxL6vgIZaGRaKlzYO+lq3CnN
# b4rtJW2d7rlTeehXtpWjggEUMIIBEDAQBgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4E
# FgQUYf1/nMEp3Df+Nzi+Hvk7FymPsrMwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBD
# AEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUfSS6
# P6qin/3ibmvelGJQhV1r1VgwOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL3BraS5x
# ZWRpbnV4LmJlL0hvbWUlMjBSb290JTIwQ0EuY3JsMEYGCCsGAQUFBwEBBDowODA2
# BggrBgEFBQcwAoYqaHR0cDovL3BraS5xZWRpbnV4LmJlL0hvbWUlMjBSb290JTIw
# Q0EuY3J0MAoGCCqGSM49BAMCA0gAMEUCIERRzfMu3vx9vb+Apud4sDkOEKhKrCEl
# gSsedbjZRJ+YAiEA8BBaOqhnbnsUBIX2nty77euunwoAHrCuWzab5xJiy0UwggOO
# MIIDM6ADAgECAhNRAAAAMJpCm89a8zgYAAAAAAAwMAoGCCqGSM49BAMCMCcxCzAJ
# BgNVBAYTAkJFMRgwFgYDVQQDEw9Ib21lIElzc3VpbmcgQ0EwHhcNMjIwNzExMDc0
# NzQ3WhcNMjQwNzExMDc1NzQ3WjAbMRkwFwYDVQQDExBEZWNlbWJyeSBRdWVudGlu
# MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjALWtmJ1AQG77y9rUBbT
# HXR9FZokTP01bBWfNzk4Kenr/Xpm7Jt09PqLoNS8ToWWKRz9EkM+jg7lnLljWKcO
# G+fT1TbaEwxOpncugnbrioQQonbdWpyn0P7PxlqjUQdWd5Z7xQ0Z8RO3vvERWtDA
# L9QH0VBHNK4WqdWh3ElV6ogJUsy5hYxVTIU0K5VEYkIT4qvqq0RdajKavGWIr57R
# EsYv52Jcyh9FNgZKGdu9NwSKZUvkwHxGsI8zmwfP1I6QRkzsqPXlpk7A8NTD3+h+
# 4Y5AprRFyAWrVNYH+UQQe2D/PjjbKtfsU9xzG9EnqJF09pVRchapis+8DbfWnoC8
# iQIDAQABo4IBfTCCAXkwOgYJKwYBBAGCNxUHBC0wKwYjKwYBBAGCNxUIhorlOcPr
# DIadiwndkzuHjPAAPqb1CYWVxXgCAWQCAQowEwYDVR0lBAwwCgYIKwYBBQUHAwMw
# DgYDVR0PAQH/BAQDAgeAMBsGCSsGAQQBgjcVCgQOMAwwCgYIKwYBBQUHAwMwHQYD
# VR0OBBYEFAkUh200U2U2epAoy2ZvT7nwAYGBMB8GA1UdIwQYMBaAFGH9f5zBKdw3
# /jc4vh75Oxcpj7KzMD4GA1UdHwQ3MDUwM6AxoC+GLWh0dHA6Ly9wa2kucWVkaW51
# eC5iZS9Ib21lJTIwSXNzdWluZyUyMENBLmNybDBJBggrBgEFBQcBAQQ9MDswOQYI
# KwYBBQUHMAKGLWh0dHA6Ly9wa2kucWVkaW51eC5iZS9Ib21lJTIwSXNzdWluZyUy
# MENBLmNydDAuBgNVHREEJzAloCMGCisGAQQBgjcUAgOgFQwTRGVjZW1icnkuUUBo
# b21lLmxhbjAKBggqhkjOPQQDAgNJADBGAiEAh39vHCgqIDL4XazyHPiChMbu0by+
# aFP7rdzlJmM0K6ACIQCaP4CXolxlzdfkJsoIoDIJUrunYIlZ0yxs9OSnG1qmCjGC
# Ad8wggHbAgEBMD4wJzELMAkGA1UEBhMCQkUxGDAWBgNVBAMTD0hvbWUgSXNzdWlu
# ZyBDQQITUQAAADCaQpvPWvM4GAAAAAAAMDAJBgUrDgMCGgUAoHgwGAYKKwYBBAGC
# NwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor
# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQUQtImBUgs
# tQKfsPtYsEFYCpf6wLIwDQYJKoZIhvcNAQEBBQAEggEARkEPt2cOia2izbLdsD02
# Md9egYYOE5XxVLOkFe+KuH4TUJ9qM9PAVRF4bgaCmV/0YQP+mthIYJ3OZGWxjkT1
# 6nKekpYm1i7n0RbdKZI84ESOsylseDaEIkVKRNKL26gNZFDwj0iRWNc57bCTnWt6
# wkwloSvt6UUF8bUXoZMmgW77zmHch9tx4r3SwhRXo+K7YalIhE8adY5BLwKvwtRI
# s32dgjEb5sGNYR7CfKKtbuIOnzo6fkuZ939Fv4kyGMKTmvOIiOPEoTJzCvbcrxgw
# oLttYAkTLBwzdjokx4AKzASq9+PSCWwKTuNhg3en6MQmJDIrMz8LbJtHb9YzT8/U
# IQ==
# SIG # End signature block