Powershell / slack / vivado > 処理終了時slack通知 (v0.7) > Generate Bitstreamまでの各処理の終了チェック

```txt:動作確認
Windows 8.1 pro (64bit)
Vivado 2015.4
```

処理終了時にslackへ通知する実装。

v0.3 > http://qiita.com/7of9/items/3d1473925fd94e2ca2db
v0.4..v0.6 > http://qiita.com/7of9/items/ef75686bc961dce90566

## code (v0.7) > 終了判定の改善

- Run Synthesis
- Run Implementation
- Generate Bistream

の各処理の終了判定を改善した。

```main.ps1
#
## 前提 > 以下のファイルがそろった環境で実行する
# 1. secret_slack_url.txt - slackのURL (git ignore対象ファイル)
# 2. target_dir.txt - Vivadoのhw/, SDK/ を含むフォルダ
# 3. このスクリプトファイル

<#
v0.7 2016 Jan 23
    - tweak check files
        + change find_implementationEndFile()
        + change find_synthesisEndFile()
v0.6 2016 Jan 23
    - check Generate Bitstream end
        + check Generate Bitsteram end at main loop
        + add find_generateBitstreamEndFile()
v0.5 2016 Jan 23
    - check Run Implementation end
        + check Run Implementation end at main loop
        + add find_implementationEndFile()
v0.4 2016 Jan 23
    - check Run Synthesis end
        + check Run Synthesis end at main loop
        + add find_synthesisEndFile()
v0.3 2016 Jan 16
    - check [vcs\ps7_init.tcl]
v0.2 2016 Jan 16
    - check [mem_init_files\ps7_init.tcl] instead of [system.hwdef]
    - add find_ps7InitTcl()
v0.1 2016 Jan 15
    - add notifyToSlack()
    - add get_lastWriteTime_hwdef()
    - add find_hwdef()
    - add get_target_dir()
    - add get_slack_url()
    - add main()
#>


function get_slack_url() 
{
    $slkurl = ( Get-Content .\\secret_slack_url.txt )
    return $slkurl
}

function get_target_dir()
{
    $trgDir = ( Get-Content .\\target_dir.txt )
    return $trgDir
}

function find_hwdef($targetDir)
{
    $hwdf = ( Get-ChildItem $targetDir -Recurse "system.hwdef" )
    return $hwdf.Fullname
}

function find_ps7InitTcl($targetDir)
{
    # vcs folder is processed lastly among 5 folders (ies / modelsim / questa / vcs / xsim)
    #
    $tcllst = ( Get-ChildItem $targetDir -Recurse "ps7_init.tcl" )
    foreach($tclfile in $tcllst) {
#        echo $tclfile.Fullname
        if ( ($tclfile.Fullname).IndexOf("vcs") -gt 0) {
            return $tclfile.Fullname
        }
    }
    return ""
}

function find_synthesisEndFile($targetDir)
{
#    $tcllst = ( Get-ChildItem $targetDir -Recurse "system_wrapper.vds" )

    $tcllst = ( Get-ChildItem $targetDir -Recurse ".vivado.end.rst" )
    foreach($tclfile in $tcllst) {
        if ( ($tclfile.Fullname).IndexOf("synth_1") -gt 0) {
            return $tclfile.Fullname
        }
    }
    return ""
}

function find_implementationEndFile($targetDir)
{
#    $tcllst = ( Get-ChildItem $targetDir -Recurse "system_wrapper.vdi" )

    $tcllst = ( Get-ChildItem $targetDir -Recurse ".route_design.end.rst" )

    foreach($tclfile in $tcllst) {
        if ( ($tclfile.Fullname).IndexOf("impl_1") -gt 0) {
            return $tclfile.Fullname
        }
    }
    return ""
}

function find_generateBitstreamEndFile($targetDir)
{
#    $tcllst = ( Get-ChildItem $targetDir -Recurse "write_bitstream.pb" )

    $tcllst = ( Get-ChildItem $targetDir -Recurse "system_wrapper.bit" )
    foreach($tclfile in $tcllst) {
        if ( ($tclfile.Fullname).IndexOf("impl_1") -gt 0) {
            return $tclfile.Fullname
        }
    }
    return ""
}

function get_lastDateTime($afile)
{
    if ( $afile.Length -eq 0 ) {
        return (Get-Date)
    }
    return (Get-ChildItem $afile).LastWriteTime
}

function notifyToSlack($msgToSlk, $slkurl) {
  $enc = [System.Text.Encoding]::GetEncoding('ISO-8859-1')
  $utf8Bytes = [System.Text.Encoding]::UTF8.GetBytes($msgToSlk)

  $notificationPayload = @{ 
    channel = "#zybo";
    username = "7of9";
    text = $enc.GetString($utf8Bytes);
  }

  Invoke-RestMethod -Uri $slkurl -Method Post -Body (ConvertTo-Json $notificationPayload)
}

function main() 
{
    $slackUrl = get_slack_url
    $targetDir = get_target_dir

    $ps7initTcl = find_ps7InitTcl $targetDir
    $GenBlockDesign_pretime = get_lastDateTime($ps7initTcl)
    echo $GenBlockDesign_pretime

    $synEndFile = find_synthesisEndFile $targetDir
    $RunSynthesis_pretime = get_lastDateTime($synEndFile)
#    echo $RunSynthesis_pretime

    $impEndFile = find_implementationEndFile $targetDir
    $RunImpl_pretime = get_lastDateTime($impEndFile)
#    echo $RunImpl_pretime

    $genBitstrEndFile = find_generateBitstreamEndFile $targetDir
    $GenBitstr_pretime = get_lastDateTime($genBitstrmEndFile)
#    echo $GenBitstr_pretime

    $msg = "Start"
    notifyToSlack $msg $slackUrl

    while ( 1 ) { 
        if (Test-Path $ps7initTcl) { # to avoid error by deletion of files during the process
            $GetBlockDesign_curtime = (Get-ChildItem $ps7initTcl).LastWriteTime
            echo "Block Design File:$GetBlockDesign_curtime"
            if ( $GetBlockDesign_curtime -gt $GenBlockDesign_pretime) {
                $GenBlockDesign_pretime = $GetBlockDesign_curtime            
                echo "Generate Block Design"
                notifyToSlack "Generated Block Design" $slackUrl
            }
        }

        if (Test-Path $synEndFile) { # to avoid error by deletion of files during the process
            $RunSynthesis_curtime = (Get-ChildItem $synEndFile).LastWriteTime
            echo "Run Synthesis File:$RunSynthesis_curtime"
            if ( $RunSynthesis_curtime -gt $RunSynthesis_pretime) {
                $RunSynthesis_pretime = $RunSynthesis_curtime            
                echo "Run Synthesis"
                notifyToSlack "Run Synthesis" $slackUrl
            }
        }

        if (Test-Path $impEndFile) { # to avoid error by deletion of files during the process
            $RunImpl_curtime = (Get-ChildItem $impEndFile).LastWriteTime
            echo "Run Implementation File:$RunImpl_curtime"
            if ( $RunImpl_curtime -gt $RunImpl_pretime) {
                $RunImpl_pretime = $RunImpl_curtime            
                echo "Run Implementation"
                notifyToSlack "Run Implementation" $slackUrl
            }
        }

        if (Test-Path $genBitstrEndFile) { # to avoid error by deletion of files during the process
            $GenBitstr_curtime = (Get-ChildItem $genBitstrEndFile).LastWriteTime
            echo "Generate Bitstream File:$GenBitstr_curtime"
            if ( $GenBitstr_curtime -gt $GenBitstr_pretime) {
                $GenBitstr_pretime = $GenBitstr_curtime            
                echo "Generate Bitstream"
                notifyToSlack "Generate Bitstream" $slackUrl
            }
        }

        sleep 5
    }

}

main
```

### 設定ファイル

以下のファイルを用意しておく。

1. secret_slack_url.txt - slackのincoming webhookのURL (<font color=red>git ignore対象ファイル</font>)
2. target_dir.txt - Vivadoのhw/, SDK/ を含む作業フォルダ

```secret_slack_url.txt
https://hooks.slack.com/services/xxxxx/xxxxx/xxxx
```

上記URLは本来のIncoming Webhookのアドレスから改変している(security対策)

```target_dir.txt
C:\ZyboDev\zybo_160112_baseDesign
```


### 結果

各処理が一回ずつ通知されるようになった。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/ae4f1562-69a0-b139-b66a-1fd0304fba83.png)


### 要改善点

現在のスクリプトではバックグラウンド実行ができない。
その理由としては、バックグラウンド実行時に実行場所が代わるために参照しているファイルが見えなくなる点。
これについてはそのうち改善を検討する。