README.md — Documentation complète du projet

Refonte action Write : modifier les XML existants au lieu de les regenerer
This commit is contained in:
2026-03-04 08:16:23 +01:00
parent c75c731ddc
commit 83df3cc4ef
5 changed files with 467 additions and 46 deletions

View File

@@ -75,9 +75,9 @@ function Invoke-EnoceanGet {
$response = Invoke-WebRequest -Uri $url -Method GET -Headers $headers -UseBasicParsing -TimeoutSec 30
# Si la reponse est un byte[] (encode=bin), decoder en string UTF-8
# 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)
return [System.Text.Encoding]::UTF8.GetString($response.Content).TrimStart([char]0xFEFF)
}
return $response.Content
}
@@ -105,28 +105,21 @@ function Send-EnoceanConfig {
[string]$Password
)
$headers = Get-AuthHeader -Username $Username -Password $Password
$authHeaders = Get-AuthHeader -Username $Username -Password $Password
$url = "$BaseUrl$ApiBasePath/files/bacnet/inputConfiguration"
Write-Log -Message "POST $url (fichier: $ZipFilename, taille: $($ZipBytes.Length) octets)" -Level INFO
# Construction multipart manuelle (compatible PS 5.1, pas de -Form)
# Construction multipart manuelle
$boundary = [System.Guid]::NewGuid().ToString("N")
$headers["Content-Type"] = "multipart/form-data; boundary=$boundary"
$encoding = [System.Text.Encoding]::ASCII
# Partie avant le fichier
$headerPart = @"
--$boundary
Content-Disposition: form-data; name="File"; filename="$ZipFilename"
Content-Type: application/octet-stream
"@
$headerPart = "--$boundary`r`nContent-Disposition: form-data; name=`"File`"; filename=`"$ZipFilename`"`r`nContent-Type: application/octet-stream`r`n`r`n"
# Partie finale
$footerPart = "`r`n--$boundary--`r`n"
$headerBytes = $encoding.GetBytes($headerPart.Replace("`n", "`r`n"))
$headerBytes = $encoding.GetBytes($headerPart)
$footerBytes = $encoding.GetBytes($footerPart)
# Assembler le body complet en byte[]
@@ -137,10 +130,39 @@ Content-Type: application/octet-stream
$bodyBytes = $bodyStream.ToArray()
$bodyStream.Close()
$response = Invoke-WebRequest -Uri $url -Method POST -Headers $headers -Body $bodyBytes -UseBasicParsing -TimeoutSec 60
# 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"])
Write-Log -Message "POST reponse : $($response.StatusCode)" -Level SUCCESS
return $response
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
}
}
Export-ModuleMember -Function Initialize-ApiClient, Get-AuthHeader, Invoke-EnoceanGet, Send-EnoceanConfig

View File

@@ -71,4 +71,30 @@ function New-EnoceanDeviceXml {
return $xml
}
Export-ModuleMember -Function Get-DeviceListFromJson, Parse-EnoceanDeviceXml, New-EnoceanDeviceXml
function Update-EnoceanDeviceId {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$XmlContent,
[Parameter(Mandatory)]
[string]$NewDeviceId
)
# Parser pour extraire les valeurs actuelles
[xml]$xml = $XmlContent
$config = $xml.EnOceanDevice.Configuration
$oldDeviceId = $config.DeviceId
$deviceType = $config.DeviceType
# Remplacement par regex sur le XML brut (preserve l'encodage et le formatage original)
$modifiedXml = $XmlContent -replace "<DeviceId>[^<]*</DeviceId>", "<DeviceId>$NewDeviceId</DeviceId>"
return @{
ModifiedXml = $modifiedXml
OldDeviceId = $oldDeviceId
DeviceType = $deviceType
}
}
Export-ModuleMember -Function Get-DeviceListFromJson, Parse-EnoceanDeviceXml, New-EnoceanDeviceXml, Update-EnoceanDeviceId

View File

@@ -20,7 +20,8 @@ function New-EnoceanZip {
$entry = $archive.CreateEntry($entryPath, [System.IO.Compression.CompressionLevel]::Optimal)
$entryStream = $entry.Open()
$writer = New-Object System.IO.StreamWriter($entryStream, [System.Text.Encoding]::UTF8)
$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
$writer = New-Object System.IO.StreamWriter($entryStream, $utf8NoBom)
$writer.Write($xmlFile.Content)
$writer.Flush()
$writer.Close()