- CLI PowerShell pour la gestion des sorties DALI adressable (ECxLightDaliA) - Action Read : rapport CSV des configurations (une ligne par output) - Action Write : modification des propriétés via POST JSON - Fallback curl.exe -k pour les automates avec problèmes SSL
236 lines
8.7 KiB
PowerShell
236 lines
8.7 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
CLI DALI pour automates Distech Controls Eclypse.
|
|
Lecture et ecriture des configurations de sorties DALI adressable (ECxLightDaliA).
|
|
|
|
.DESCRIPTION
|
|
DaliACLI permet de gerer les configurations DALI adressable sur des automates
|
|
Distech Controls Eclypse en utilisant leur API REST v2.
|
|
|
|
Action READ : Lit la configuration des modules ECxLightDaliA de chaque automate
|
|
et genere un fichier CSV avec une ligne par sortie (output).
|
|
|
|
Action WRITE : Modifie les proprietes des sorties DALI a partir du CSV.
|
|
Toutes les proprietes de chaque ligne sont reecrites.
|
|
|
|
.PARAMETER Action
|
|
Action a effectuer :
|
|
Read - Lire la configuration et generer un CSV de sortie
|
|
Write - Ecrire les proprietes depuis le CSV vers les automates
|
|
|
|
.PARAMETER CsvInput
|
|
Chemin vers le fichier CSV d'entree (separateur point-virgule).
|
|
Pour Read : colonnes minimales Hostname, Current Ip, HttpPort, HttpsPort.
|
|
Pour Write : CSV enrichi genere par l'action Read.
|
|
|
|
.PARAMETER Username
|
|
Nom d'utilisateur pour l'authentification API (defaut: admin).
|
|
Peut etre surcharge par la colonne Username du CSV.
|
|
|
|
.PARAMETER Password
|
|
Mot de passe pour l'authentification API (defaut: vide).
|
|
Peut etre surcharge par la colonne Password du CSV.
|
|
|
|
.EXAMPLE
|
|
.\DaliACLI.ps1 -Action Read -CsvInput ".\automates.csv"
|
|
|
|
Lit la configuration DALI de tous les automates listes dans le CSV.
|
|
Genere un fichier dali_YYYY-MM-DD_HHhMM.csv dans le repertoire courant.
|
|
|
|
.EXAMPLE
|
|
.\DaliACLI.ps1 -Action Write -CsvInput ".\dali_2026-04-02_14h30.csv" -Password "MonMotDePasse"
|
|
|
|
Ecrit les proprietes du CSV vers les automates.
|
|
|
|
.EXAMPLE
|
|
Get-Help .\DaliACLI.ps1 -Detailed
|
|
|
|
Affiche cette aide detaillee.
|
|
|
|
.NOTES
|
|
Prerequis : PowerShell 5.1+ (inclus dans Windows 10/11)
|
|
API : Distech Controls Eclypse REST API v2
|
|
Securite : TLS 1.2, certificats auto-signes acceptes
|
|
#>
|
|
|
|
param(
|
|
[Parameter(Mandatory)]
|
|
[ValidateSet("Read", "Write")]
|
|
[string]$Action,
|
|
|
|
[Parameter(Mandatory)]
|
|
[string]$CsvInput,
|
|
|
|
[string]$Username = "admin",
|
|
|
|
[string]$Password = ""
|
|
)
|
|
|
|
# Performance : desactiver la barre de progression Invoke-WebRequest
|
|
$ProgressPreference = 'SilentlyContinue'
|
|
|
|
# Import des modules
|
|
$modulesPath = Join-Path $PSScriptRoot "modules"
|
|
Import-Module (Join-Path $modulesPath "Logger.psm1") -Force
|
|
Import-Module (Join-Path $modulesPath "CsvHandler.psm1") -Force
|
|
Import-Module (Join-Path $modulesPath "ApiClient.psm1") -Force
|
|
Import-Module (Join-Path $modulesPath "DaliParser.psm1") -Force
|
|
|
|
# Initialisation
|
|
Initialize-Logger
|
|
Initialize-ApiClient
|
|
|
|
Write-Log -Message "=== DaliACLI demarre - Action: $Action ===" -Level INFO
|
|
|
|
# Chemin de l'API DALI
|
|
$daliApiPath = "/api/rest/v2/services/subnet/devices/light-sunblind/modules"
|
|
|
|
# Lecture du CSV d'entree
|
|
$csvRows = Read-AutomateCsv -CsvPath $CsvInput
|
|
|
|
# ============================================================
|
|
# ACTION READ : Lire la config DALI de chaque automate
|
|
# ============================================================
|
|
if ($Action -eq "Read") {
|
|
$timestamp = Get-Date -Format "yyyy-MM-dd_HH\hmm"
|
|
$CsvOutput = Join-Path (Get-Location) "dali_$timestamp.csv"
|
|
Write-Log -Message "CSV de sortie : $CsvOutput" -Level INFO
|
|
|
|
$allOutputRows = @()
|
|
|
|
# Deduplication des automates par IP (le CSV d'entree a une ligne par automate)
|
|
$uniqueAutomates = $csvRows | Sort-Object -Property "Current Ip" -Unique
|
|
|
|
foreach ($automate in $uniqueAutomates) {
|
|
$hostname = $automate.Hostname
|
|
$ip = $automate."Current Ip"
|
|
|
|
Update-Stats -Counter AutomatesTotal
|
|
|
|
try {
|
|
$baseUrl = Get-BaseUrl -Automate $automate
|
|
if (-not $baseUrl) {
|
|
Write-Log -Message "[$hostname] Aucun port HTTP/HTTPS valide - ignore" -Level WARN
|
|
Update-Stats -Counter AutomatesError
|
|
continue
|
|
}
|
|
|
|
$creds = Get-Credentials -Automate $automate -DefaultUsername $Username -DefaultPassword $Password
|
|
$url = "$baseUrl$daliApiPath/"
|
|
|
|
Write-Log -Message "[$hostname] $url (user: $($creds.Username))" -Level INFO
|
|
|
|
# GET modules DALI
|
|
$jsonContent = Invoke-ApiGet -Url $url -Username $creds.Username -Password $creds.Password
|
|
|
|
# Parser et filtrer les modules ECxLightDaliA
|
|
$daliOutputs = Get-DaliAModules -JsonContent $jsonContent
|
|
|
|
if ($daliOutputs.Count -eq 0) {
|
|
Write-Log -Message "[$hostname] Aucun module ECxLightDaliA trouve" -Level WARN
|
|
continue
|
|
}
|
|
|
|
Write-Log -Message "[$hostname] $($daliOutputs.Count) sortie(s) ECxLightDaliA trouvee(s)" -Level INFO
|
|
|
|
# Creer une ligne CSV par output
|
|
foreach ($output in $daliOutputs) {
|
|
# Copier toutes les colonnes source de l'automate
|
|
$row = [ordered]@{}
|
|
foreach ($prop in $automate.PSObject.Properties) {
|
|
$row[$prop.Name] = $prop.Value
|
|
}
|
|
# Ajouter les colonnes DALI
|
|
$row["ModuleKey"] = $output.ModuleKey
|
|
$row["ModuleName"] = $output.ModuleName
|
|
$row["OutputKey"] = $output.OutputKey
|
|
$row["OutputName"] = $output.OutputName
|
|
$row["ControlGearKey"] = $output.ControlGearKey
|
|
$row["Groups"] = $output.Groups
|
|
$row["SystemFailLevel"] = $output.SystemFailLevel
|
|
$row["PowerOnLevel"] = $output.PowerOnLevel
|
|
$row["MinDimmingLevel"] = $output.MinDimmingLevel
|
|
$row["DefaultValue"] = $output.DefaultValue
|
|
$row["DimmingTime"] = $output.DimmingTime
|
|
$row["MaxDimmingLevel"] = $output.MaxDimmingLevel
|
|
|
|
$allOutputRows += [PSCustomObject]$row
|
|
Update-Stats -Counter OutputsProcessed
|
|
|
|
Write-Log -Message "[$hostname] M$($output.ModuleKey)_O$($output.OutputKey) ($($output.OutputName)) - Groups: $($output.Groups)" -Level SUCCESS
|
|
}
|
|
}
|
|
catch {
|
|
Write-Log -Message "[$hostname] ERREUR : $($_.Exception.Message)" -Level ERROR
|
|
Update-Stats -Counter AutomatesError
|
|
}
|
|
}
|
|
|
|
# Ecriture du CSV de sortie
|
|
if ($allOutputRows.Count -gt 0) {
|
|
Write-OutputCsv -OutputRows $allOutputRows -OutputPath $CsvOutput
|
|
}
|
|
else {
|
|
Write-Log -Message "Aucune sortie trouvee - CSV non genere" -Level WARN
|
|
}
|
|
}
|
|
|
|
# ============================================================
|
|
# ACTION WRITE : Ecrire la config DALI sur chaque automate
|
|
# ============================================================
|
|
elseif ($Action -eq "Write") {
|
|
# Grouper les lignes par automate (Current Ip)
|
|
$automateGroups = $csvRows | Group-Object -Property "Current Ip"
|
|
|
|
foreach ($automateGroup in $automateGroups) {
|
|
$ip = $automateGroup.Name
|
|
$rows = $automateGroup.Group
|
|
$hostname = $rows[0].Hostname
|
|
|
|
Update-Stats -Counter AutomatesTotal
|
|
|
|
try {
|
|
$baseUrl = Get-BaseUrl -Automate $rows[0]
|
|
if (-not $baseUrl) {
|
|
Write-Log -Message "[$hostname] Aucun port HTTP/HTTPS valide - ignore" -Level WARN
|
|
Update-Stats -Counter AutomatesError
|
|
continue
|
|
}
|
|
|
|
$creds = Get-Credentials -Automate $rows[0] -DefaultUsername $Username -DefaultPassword $Password
|
|
$url = "$baseUrl$daliApiPath"
|
|
|
|
Write-Log -Message "[$hostname] $url (user: $($creds.Username))" -Level INFO
|
|
|
|
# Grouper par ModuleKey pour envoyer un POST par module
|
|
$moduleGroups = $rows | Group-Object -Property ModuleKey
|
|
|
|
foreach ($moduleGroup in $moduleGroups) {
|
|
$moduleKey = $moduleGroup.Name
|
|
$outputRows = $moduleGroup.Group
|
|
|
|
Write-Log -Message "[$hostname] Module $moduleKey : $($outputRows.Count) sortie(s) a ecrire" -Level INFO
|
|
|
|
# Construire le body JSON
|
|
$jsonBody = Build-ModuleWriteBody -ModuleKey $moduleKey -OutputRows $outputRows
|
|
|
|
Write-Log -Message "[$hostname] Module $moduleKey body: $jsonBody" -Level INFO
|
|
|
|
# POST vers l'API
|
|
Invoke-ApiPost -Url $url -JsonBody $jsonBody -Username $creds.Username -Password $creds.Password
|
|
|
|
Update-Stats -Counter OutputsProcessed -Increment $outputRows.Count
|
|
|
|
Write-Log -Message "[$hostname] Module $moduleKey : configuration ecrite avec succes" -Level SUCCESS
|
|
}
|
|
}
|
|
catch {
|
|
Write-Log -Message "[$hostname] ERREUR : $($_.Exception.Message)" -Level ERROR
|
|
Update-Stats -Counter AutomatesError
|
|
}
|
|
}
|
|
}
|
|
|
|
# Resume final
|
|
Write-Summary
|