Files
gfx-enocean/modules/ApiClient.psm1
Charles bd4fde8190 Correction README.md
Ajout modification du fichier Project.gfx
2026-03-05 10:36:52 +01:00

213 lines
6.3 KiB
PowerShell

# Module ApiClient - Communication REST API Eclypse
function Initialize-ApiClient {
[CmdletBinding()]
param()
# Forcer TLS 1.2
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# Desactiver la verification SSL (certificats auto-signes)
if (-not ([System.Management.Automation.PSTypeName]'TrustAllCertsPolicy').Type) {
Add-Type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
}
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
Write-Log -Message "ApiClient initialise (TLS 1.2, SSL bypass)" -Level INFO
}
function Get-AuthHeader {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$Username,
[Parameter(Mandatory)]
[AllowEmptyString()]
[string]$Password
)
$pair = "${Username}:${Password}"
$bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
$base64 = [System.Convert]::ToBase64String($bytes)
return @{
"Authorization" = "Basic $base64"
"Accept" = "application/json, text/json, text/x-json, text/javascript, application/xml, text/xml, text/plain"
"User-Agent" = "EC-gfxProgram/7.9.26006.1 (DC_API:v1; Win32NT 6.2)"
}
}
function Invoke-EnoceanGet {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$BaseUrl,
[Parameter(Mandatory)]
[string]$ApiBasePath,
[Parameter(Mandatory)]
[string]$ResourcePath,
[Parameter(Mandatory)]
[string]$Username,
[Parameter(Mandatory)]
[AllowEmptyString()]
[string]$Password,
[switch]$RawBytes
)
$headers = Get-AuthHeader -Username $Username -Password $Password
$url = "$BaseUrl$ApiBasePath/$($ResourcePath.TrimStart('/'))"
Write-Log -Message "GET $url" -Level INFO
$response = Invoke-WebRequest -Uri $url -Method GET -Headers $headers -UseBasicParsing -TimeoutSec 30
# Retourner les bytes bruts si demande (pour fichiers binaires comme .gfx)
if ($RawBytes) {
if ($response.Content -is [byte[]]) {
return , $response.Content
}
return , [System.Text.Encoding]::UTF8.GetBytes($response.Content)
}
# Si la reponse est un byte[] (encode=bin), decoder en string UTF-8 sans BOM
if ($response.Content -is [byte[]]) {
return [System.Text.Encoding]::UTF8.GetString($response.Content).TrimStart([char]0xFEFF)
}
return $response.Content
}
function Send-MultipartFile {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$BaseUrl,
[Parameter(Mandatory)]
[string]$ApiBasePath,
[Parameter(Mandatory)]
[string]$ResourcePath,
[Parameter(Mandatory)]
[byte[]]$FileBytes,
[Parameter(Mandatory)]
[string]$Filename,
[Parameter(Mandatory)]
[string]$Username,
[Parameter(Mandatory)]
[AllowEmptyString()]
[string]$Password
)
$authHeaders = Get-AuthHeader -Username $Username -Password $Password
$url = "$BaseUrl$ApiBasePath/$($ResourcePath.TrimStart('/'))"
Write-Log -Message "POST $url (fichier: $Filename, taille: $($FileBytes.Length) octets)" -Level INFO
# Construction multipart manuelle
$boundary = [System.Guid]::NewGuid().ToString("N")
$encoding = [System.Text.Encoding]::ASCII
$headerPart = "--$boundary`r`nContent-Disposition: form-data; name=`"File`"; filename=`"$Filename`"`r`nContent-Type: application/octet-stream`r`n`r`n"
$footerPart = "`r`n--$boundary--`r`n"
$headerBytes = $encoding.GetBytes($headerPart)
$footerBytes = $encoding.GetBytes($footerPart)
# Assembler le body complet en byte[]
$bodyStream = New-Object System.IO.MemoryStream
$bodyStream.Write($headerBytes, 0, $headerBytes.Length)
$bodyStream.Write($FileBytes, 0, $FileBytes.Length)
$bodyStream.Write($footerBytes, 0, $footerBytes.Length)
$bodyBytes = $bodyStream.ToArray()
$bodyStream.Close()
# Utiliser HttpWebRequest directement pour envoyer les bytes bruts sans troncature
$request = [System.Net.HttpWebRequest]::Create($url)
$request.Method = "POST"
$request.ContentType = "multipart/form-data; boundary=$boundary"
$request.ContentLength = $bodyBytes.Length
$request.Timeout = 60000
$request.UserAgent = $authHeaders["User-Agent"]
$request.Accept = $authHeaders["Accept"]
$request.Headers.Add("Authorization", $authHeaders["Authorization"])
try {
$reqStream = $request.GetRequestStream()
$reqStream.Write($bodyBytes, 0, $bodyBytes.Length)
$reqStream.Close()
$response = $request.GetResponse()
$statusCode = [int]$response.StatusCode
$response.Close()
Write-Log -Message "POST reponse : $statusCode" -Level SUCCESS
}
catch [System.Net.WebException] {
$responseBody = ""
if ($_.Exception.Response) {
$stream = $_.Exception.Response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($stream)
$responseBody = $reader.ReadToEnd()
$reader.Close()
$stream.Close()
}
Write-Log -Message "POST erreur $($_.Exception.Message) - Reponse serveur: $responseBody" -Level ERROR
throw
}
}
function Send-EnoceanConfig {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$BaseUrl,
[Parameter(Mandatory)]
[string]$ApiBasePath,
[Parameter(Mandatory)]
[byte[]]$ZipBytes,
[Parameter(Mandatory)]
[string]$ZipFilename,
[Parameter(Mandatory)]
[string]$Username,
[Parameter(Mandatory)]
[AllowEmptyString()]
[string]$Password
)
Send-MultipartFile `
-BaseUrl $BaseUrl `
-ApiBasePath $ApiBasePath `
-ResourcePath "files/bacnet/inputConfiguration" `
-FileBytes $ZipBytes `
-Filename $ZipFilename `
-Username $Username `
-Password $Password
}
Export-ModuleMember -Function Initialize-ApiClient, Get-AuthHeader, Invoke-EnoceanGet, Send-MultipartFile, Send-EnoceanConfig