diff --git a/examples/validate_firmware_write.html b/examples/validate_firmware_write.html
new file mode 100644
index 0000000..640d146
--- /dev/null
+++ b/examples/validate_firmware_write.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/validate_firmware_write.jl b/examples/validate_firmware_write.jl
index 3d6bbf7..c05d8fd 100644
--- a/examples/validate_firmware_write.jl
+++ b/examples/validate_firmware_write.jl
@@ -9,6 +9,7 @@ begin
using Pkg
Pkg.activate(".")
using CSV
+ using SQLite
using DataFrames
using PlutoUI
using PSBoardDataBase
@@ -72,7 +73,7 @@ second_run_writing_result = filter(:motherboard_id => (id -> begin
end), second_run_result)
# ╔═╡ 383e1e04-ba3e-49bf-9f99-46c53b37204b
-map(eachrow(second_run_writing_result)) do row
+combined_result = map(eachrow(second_run_writing_result)) do row
slavelog_dir = "../test/input/slavelogs/main/"
logfilename = "$(row.motherboard_id)_$(row.runid).txt"
logfilepath = joinpath(slavelog_dir, logfilename)
@@ -92,6 +93,106 @@ md"""
**Looks OK**
"""
+# ╔═╡ a721c7e2-a19e-4a8a-87ba-6809fb9d1cc4
+combined_result.psbid |> unique |> length
+
+# ╔═╡ e0411f36-fa75-445c-a275-b58cfa5ec73c
+filter(:qspip => ==(1), combined_result).psbid |> unique |> length
+
+# ╔═╡ 5d66892d-3d12-4f0a-a128-18b95eab7123
+filter(:qspip => ==(0), combined_result).psbid |> unique |> length
+
+# ╔═╡ abcf438d-7ebe-461d-bc19-1dedcf4861cc
+filter(:slavelog_psbid => ismissing, combined_result).psbid |> unique |> length
+
+# ╔═╡ 8ccfce73-9fdf-48bd-a78f-39bfda3c7121
+combined_by_psbid = combine(groupby(combined_result, :psbid), [:slavelog_psbid, :qspip] => ((slavelog_psbid, qspip) -> begin
+ # @info "" slavelog_psbid qspip
+ if any(==(1), qspip)
+ [(; qspip_ok = true)]
+ else
+ [(; qspip_ok = false)]
+ end
+end) => [:qspip_ok])
+
+# ╔═╡ eb77e281-1d5e-4ba1-a6d8-8e7235d5a7d0
+filter(:qspip_ok => !, combined_by_psbid).psbid
+
+# ╔═╡ cb2d2f25-e008-4f62-a6a0-83febaddb2ef
+md"""
+# Compare with QAQC
+"""
+
+# ╔═╡ c0d22530-f0a0-461d-b15c-779b1b6a2a42
+db = SQLite.DB("../psboard_qaqc.db")
+
+# ╔═╡ 2244386c-5608-4914-abdd-c7403c1f0a74
+SQLite.tables(db)
+
+# ╔═╡ 0d502ae5-a7a3-44f7-bfb9-49cf77e22cfe
+ps_boards = DBInterface.execute(db, "select * from ps_boards") |> DataFrame
+
+# ╔═╡ 516e6255-63d4-4e83-9d9d-4a3dc46b8e56
+qaqc_single_result = DBInterface.execute(db, "select * from qaqc_single_run_results") |> DataFrame |> (df -> groupby(df, :psboard_id))
+
+# ╔═╡ 9a1eb3d1-ed35-4032-b345-e18fa0657268
+qaqc_extra_result = DBInterface.execute(db, "select * from qaqc_extra_run_results") |> DataFrame |> (df -> groupby(df, :psboard_id))
+
+# ╔═╡ f7710e79-86e4-4048-b3cf-03c7097b388c
+qaqc_dispatch = DBInterface.execute(db, "select * from qaqc_dispatch") |> DataFrame
+
+# ╔═╡ 2beefcb1-a3e7-485c-bcca-d2fb1624119f
+qaqc_dispatch.psb_id .∈ Ref(filter(:qspip_ok => identity, combined_by_psbid).psbid)
+
+# ╔═╡ f334909b-0a09-42fc-8fc0-64978ca6e067
+let
+ passed = filter(:qspip_ok => identity, combined_by_psbid).psbid
+ @info "" passed
+ filter(qaqc_dispatch.psb_id) do psbid
+ !(psbid in passed)
+ end
+end
+
+# ╔═╡ 2ef8303f-84a9-4053-a38e-b31fcd766796
+let
+ qspi_tried = combined_by_psbid.psbid
+ qspi_passed = filter(:qspip_ok => identity, combined_by_psbid).psbid
+ Iterators.flatmap(qaqc_dispatch.psb_id) do psbid
+ if psbid in qspi_passed
+ return []
+ end
+ [(; psbid, qspi_tried = psbid in qspi_tried, qspi_passed = psbid in qspi_passed)]
+ end |> DataFrame
+end
+
+# ╔═╡ f16b9b80-242e-4349-99ee-a8de614a7b3e
+md"""
+## diff from dispatch list
+差分は全て、以下の2通りのいずれかに該当する。
+また、61はプレ量産なので、出荷リストに含まれない。
+
+### QSPIパラメータ書き込みしようとしたが、失敗したもの
+```
+61
+896
+1094
+1142
+1160
+```
+
+### 通常のファームウェア・QSPIパラメータ書き込み試験で漏れていて、あとで手動で統合試験ベンチで書き込んだもの
+```
+110
+108
+483
+484
+1402
+1401
+1553
+1533
+```
+"""
+
# ╔═╡ Cell order:
# ╠═1d057382-316a-11f0-1fbd-c9c7f879bbb1
# ╠═3bf488c4-cd2a-4b2c-b2ee-a6f8d84368df
@@ -109,3 +210,20 @@ md"""
# ╠═2bd267ea-78ab-454e-93e4-81a2f7a5d671
# ╠═383e1e04-ba3e-49bf-9f99-46c53b37204b
# ╠═162ef015-7acd-4431-91bd-f3c5f1d26f8a
+# ╠═a721c7e2-a19e-4a8a-87ba-6809fb9d1cc4
+# ╠═e0411f36-fa75-445c-a275-b58cfa5ec73c
+# ╠═5d66892d-3d12-4f0a-a128-18b95eab7123
+# ╠═abcf438d-7ebe-461d-bc19-1dedcf4861cc
+# ╠═8ccfce73-9fdf-48bd-a78f-39bfda3c7121
+# ╠═eb77e281-1d5e-4ba1-a6d8-8e7235d5a7d0
+# ╠═cb2d2f25-e008-4f62-a6a0-83febaddb2ef
+# ╠═c0d22530-f0a0-461d-b15c-779b1b6a2a42
+# ╠═2244386c-5608-4914-abdd-c7403c1f0a74
+# ╠═0d502ae5-a7a3-44f7-bfb9-49cf77e22cfe
+# ╠═516e6255-63d4-4e83-9d9d-4a3dc46b8e56
+# ╠═9a1eb3d1-ed35-4032-b345-e18fa0657268
+# ╠═f7710e79-86e4-4048-b3cf-03c7097b388c
+# ╠═2beefcb1-a3e7-485c-bcca-d2fb1624119f
+# ╠═f334909b-0a09-42fc-8fc0-64978ca6e067
+# ╠═2ef8303f-84a9-4053-a38e-b31fcd766796
+# ╠═f16b9b80-242e-4349-99ee-a8de614a7b3e