WordPress on Nginx on Windows。その1

追記(2019/04/13): Windows10でNginx+MariaDB+Wordpressをインストールする。その1に書き直しました。

システムの更新に伴って、もう数ヶ月も自宅サーバのブログが動いてません。いろいろ試してうまくいかないのでどうしようかと思ってるんですが、とりあえず一時退避でこちらのブログを使っています。

なぜそんなことになったかというと、まずプラットフォームの NetBSD が 8.0 をリリースしたのでアップグレードし、さらに PHP での MySQL サポートをこれまでの mysql ドライバが非推奨になり、mysqli ドライバに切り替わったことで DB への接続が変わってしまい、また Apache も 2.4系で設定が変わったという複合的な要因があったためで。

もういっそ Nginx にしてしまおうか、それなら uWSGI も使えるし、ブログは WordPress から Mezzanine にお引越しすればいいか、と考えたのですが、うちのサーバでは Perl CGI や mailman なども動いていて、なかなかめんどくさい。

全部 Nginx でできればいいんですが、PHP に関しては FastCGI にするか、uWSGI の Emperor モードにするかも悩ましいところですし、Perl CGI に至っては「もしかしてこれは Apache に処理させて、Nginx に proxy させるのが一番なのでは…」などと思い始める始末。古い技術に引きずられてしまっています。

ただ、WordPress にはこれまで書きまくった大量のエントリがあって、実はちょくちょく参照したい。データベースの方は dump してあるんですが、そのままではテキストエディタで読み込んでも使えない(1行が長すぎるなど)のため、ローカルに MariaDB をインストールして読み込ませました。そこに HeidiSQL を使ってクエリを飛ばして検索しているんですが、どうにも使いづらい。なのでいっそ、暫定的にローカルブログにしてしまって、ブラウザからアクセスするほうがいいかと思ったのがきっかけです。

その裏では新しく Manjaro Linux を使ってサーバを置き換えようかと準備は進めているのですが…。ところで記法は Nginx なんでしょうか、nginx なんでしょうか。


閑話休題。

Apache はモジュールの管理などいろいろと無理しているところもあり、設定も複雑化してきているので「管理で楽をしたい」というならば Nginx のほうがよさそうな感じです。
そうしたことを見据え、さらには慣れておきたいということもあって今回は Nginx を動かし、その上で WordPress をサーブさせるという方向でいじってみます。
実はすでに MariaDB はインストールされているため、そのへんはここでは触れません。

Nginx のインストール

まずはNginxのインストールです。一応 Cygwin64 などは使っているのですが、そこらへんは今回あまり関係ありません。
Nginx のサイトから、ダウンロードページに飛んで、Mainline のnginx/Windows-1.15.5をダウンロードします。
これは ZIP ファイルになっていますので、ダウンロードしたら展開し、いつもどおり c:\Apps\Nginx 以下に配置します。

そうしたら何もせずにいきなり nginx.exe をクリックすると、Nginxが常駐しサービスが始まります。ポート80を開くので Windows ファイアウォールの警告が出ますが、これは OK で先に進めます。あくまでデフォルト状態なので、コンテンツは Welcome メッセージだけですが、ブラウザで http://127.0.0.1/ にアクセスすると "Welcome to nginx!" というメッセージが表示されます。

PHPのインストール

Nginx が動いたらPHPをインストールします。PHPのダウンロードページに飛ぶとWindows用のリンクがあるので、そこを開きます。そこには64/32bit、Thread Safe/Non Thread Safe という形で4つのリンクがありますが、こちらの環境は Windows 10 64bit なので 64bit の Non Thread Safe 版をダウンロードします。
Thread Safe と Non Thread Safe のどちらを選ぶべばよいかは、PHP の FAQ に書かれています。

==
What does thread safety mean when downloading PHP?
Thread Safety means that binary can work in a multithreaded webserver context, such as Apache 2 on Windows. Thread Safety works by creating a local storage copy in each thread, so that the data won't collide with another thread.

So what do I choose? If you choose to run PHP as a CGI binary, then you won't need thread safety, because the binary is invoked at each request. For multithreaded webservers, such as IIS5 and IIS6, you should use the threaded version of PHP.

PHPをダウンロードする際に、thread safetyとは何を意味していますか?
thread safety は、たとえば Windows 上の Apache2 のようなマルチスレッドの Web サーバ環境で動作できるバイナリのことです。Thread Safety はそれぞれのスレッドに対してローカルなストレージコピーを作成することで、他のスレッドとデータの衝突が起きないように動作します。
それではどちらを選べばよいか? もしも PHP を CGI バイナリとして走らせるのであれば、thread safety である必要はありません。なぜならバイナリはリクエストごとに起動されるからです。IIS5 や IIS6 のようなマルチスレッド Web サーバを使用するのなら、thread safe な PHP を使うべきです。
==

ということで、FastCGI を使う場合には一番上にあるNon Thread Safeを選べばよいでしょう。
さて、ダウンロードした PHP はこれもまた ZIP ファイルなので、展開して同じように c:\Apps\PHP に置きます。あまりルートディレクトリがごちゃごちゃするのは好きではないので。
配置したら、環境変数を設定します。



一旦システム環境変数に PHPPATH という名前で環境変数を作成し、それを PATH に参照させます。


自分の場合は、長い文字列のなかでパスのだぶりを見つけるのがとても面倒なのでこうしています。
特に「特定のパスを参照させたくないとき」にダブりがあると、期待された結果が得られないことがあるのですが、こうすることでわかりやすくしています。

パスの設定が終わったら新規でコマンドプロンプトを開き、

$php -r "phpinfo();" | grep -i thread
Thread Safety => disabled

として動作しているのを確認します。
インストールされたものを眺めてみると、 c:\Apps\PHP\ext 以下にモジュールが一通り入っていますので、iconv や mbstring、gd、exif などのインストールは必要なさそうです。また MySQL ドライバとしては、mysqli と pdo_mysql が両方含まれています。WordPress からはどちらでも使えるようなので、心に留めておきます。

FastCGIの設定

Nginx と PHP をインストールしたので、WordPress をインストールする前に FastCGI で PHP を動作させる確認をします。
参考にするのは、Nginx のサイトから PHP-FastCGI on WindowsPHP FastCGI Exampleです。それに PHP のサイトにも FastCGI Process Manager (FPM) というページがありますが、これは FPM を使用する場合なので今回は無関係です。そもそも Windows 版には php-fpm.exe は付属していません。

上記のページには、コンソールを隠した状態で起動したい場合についても書いてあります。lighttph のサイトからRunHiddenConsole.exeというヘルパーアプリをダウンロードして使えばいいとありますが、ここでは使いません。常時サービスするわけでもありませんので。

さて、FastCGI を動かすには、すでにインストールされている php-cgi.exe を引数付きで起動すればよいようです。

php-cgi.exe -b 127.0.0.1:9123

ローカルホストのポート9123にバインドする、というオプションで起動します。ポート番号は任意ですが、WikipediaのTCPやUDPにおけるポート番号の一覧などを参考に空きポートを利用するのがよいでしょう。特にこだわりはないので上記のポート番号を利用することにします。ただし、外部に開放する場合にはファイアウォールなどでポートアクセスを弾く設定も必要になりますので、下手にこだわるよりはデフォルトのまま利用したほうが、あとから見て「これなんのポートだっけ?」ということになりにくいです。

さて、コマンドプロンプトを開いて上記のコマンドを実行すると、コンソールには何も表示されずにプログラムは実行状態になります。これはリクエストを待っている状態です。

次に Nginx の設定を行います。

まずはドキュメントルートを作成します。ここでは c:\srv\www としておきます。これは Linux Foundation の Filesystem Hierarchy Standard (FHS) に定義されているディレクトリ構造によります。詳細は 3.17. /srv : Data for services provided by this system を参照。ただし Linux Distribution によっては /var/www などとしているものもあります。このへんについてはコンセンサスが取れていないようですが、ここでは直感的に「サーブされるデータ」ということで /srv にしておきます。

ドキュメントルートが決まったら、これをnginx.conf に反映します。

上記ページには、
root c:/www;

location ~ \.php$ {
    fastcgi_pass   127.0.0.1:9123;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
}

となっていますが、c:\Apps\Nginx\conf\nginx.conf を以下のように修正します。

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9123
#
location ~ \.php$ {
    root           c:/srv/www;
    fastcgi_pass   127.0.0.1:9123;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $fastcgi_script_name;
    include        fastcgi_params;
    include        fastcgi.conf;
}

念のため、何かあれば参照できるようにもともとの nginx.conf は nginx.conf.orig とでも名前を変えて保存してから、編集します。実際には nginx.con の63行目から同様の記述があるので、そこのコメントを外していじればOKです。

ここでひとつ注意しなくてはならないのは、コンソール(コマンドプロンプト)から nginx.exe を起動すると、それを終了することが困難な点です。これはバッチファイルでも同じ。
すでに nginx を起動しているコンソールがあるとして、別のコンソールから nginx -s stop などとしても

nginx: [alert] could not open error log file: CreateFile() "logs/error.log" failed (3: The system cannot find the path specified)
2018/10/29 13:04:11 [emerg] 1588#5708: CreateFile() "C:\Apps\Nginx/conf/nginx.conf" failed (3: The system cannot find the path specified)

などとでてきて停止も終了もできません。もちろん nginx.conf を更新してから reload させようとしても同じようです。そこでコンソールを閉じても、実はバックグラウンドジョブとして nginx が生き残ってしまうので、nginx.conf を修正して再起動したつもりでもちゃんと反映されない、ということになります。

コンソールから起動した nginx.exe を終了させるには、どうやらタスクマネージャーから nginx.exe を探して一つづつ「タスクの終了」をするか、別のコンソールから taskkill /f /im nginx.exe するしかないようです。

一方、エクスプローラから nginx.exe を直接起動したり、ショートカットを作ってそこから起動した場合にはシグナルを受け取って正常に終了するようです。

php-cgi と nginx を起動したら、PHP のテストファイルを用意します。以下の1行のみのファイルを index.php として c:\srv\www に保存します。

<?php phpinfo(); ?>

そしてブラウザから http://127.0.0.1/index.php にアクセスし、エラーとか応答なしとか "No input file specified." などという文字ではなく、下のようなページが表示されればOKです。

卓上バイス FV-150。

ボール盤用卓上バイス(ベタバイス)トラスコ中山のFV-150を購入しました。ボール盤を簡易フライスとして使いたくて、PROXXONのNo.27150マイクロクロステーブルと組み合わせようと思いまして。

FreeCADでざっくり図面を書いて、固定溝の位置を確認したらいけそうだったので、一番安かったヨドバシカメラに注文しました。


箱。中には特に緩衝材などなく、ほぼぴったりサイズでビニール袋に包まれて入ってました。


取り出したところ。グリスでベタベタです。どこを触ってもベタベタ。使う前にある程度拭き取らないと。


開口部拡大。検査証も入っていて、開口150mm合格になってました。


実はマイクロクロステーブルには、45度の角度で固定して使おうと考えています。サイズ的にも4ヶ所留めは無理なので2ヶ所のみになりますが、マイクロクロステーブルに付属のM8x25のボルトにM8x22のワッシャを噛ませば固定できるかなと考えています。強度的には物足りませんが、金属を削るわけではないのでまずはこれでやってみようかと。45度の角度だしはシンワの止めスコヤでやります。

木工資材とボール盤台。

なんで木工資材の特徴などについてメモしているかというと、若干水濡れなども予想される場所に設置するボール盤台を作ろうかと思っているからです。

今使っているKIRA NSD-13の台は木の板を組んでコロ(キャスター)をつけたものですが、そもそもそのコロが金属製でかつ錆びついて動かなくなっていて、さらに耐荷重足りてなさそうなのと、台自体が腐って脆くなってきているから。
NSD-13は取扱説明書によれば67kgあります。成人男性一人分ですが、静荷重として常時かかるとなるとコロの耐荷重は2倍以上はみておきたいところ。

ちなみに台車として考えたとき、コロの最大荷重と安全荷重の考え方は、

$最大積載荷重 daN=(キャスター数 \times 許容荷重daN) \times 0.7 - (台車荷重daN)$

ただし daN はデカニュートン(10N)です。
ちなみに1kgf(キログラム重)は標準重力下での質量1kgの物体の重量で、1kgf=9.80665N となります。
つまり1daN=10N=1.01972kgfであり、daNをそのままkgfと読み替えても誤差は2%以内になるため都合がいいですね。

安全荷重はさらにその 0.5倍から0.7倍程度を見込むことが大切で、そこには台車の上で重心が偏って貨物が置かれた状況などもざっくりと勘案されています。

運搬したい貨物の重量が100kgf(≒100daN)であれば、安全サイドに振るならコロの合計許容荷重は300kgf、通常でも200kgfは見ておきましょうということになります。

ところで上記のMathJAXでの記法、ちゃんと動いてるかな…。

木工用の木材について。

最近は木でなにかを作るのが流行っているのか、ホームセンターでも工作室を用意していたり、ガーデン用ラティスとかカラフルなレンガタイルとか、あるいは継ぎ手とか柱固定金具とかいろいろ品揃えが豊富です。

当然ながら工作するための電動工具もピンからキリまで、いろいろあります。

そんななかで、たぶん一番よくわからないのが木材ではないでしょうか。どの木材がどういう用途に向いて、あるいは向いていないかというのは、自分も含めて初心者にはなかなかわからないものです。

杉材、ヒノキ材、オークなどの無垢材、木片を加圧接着したパインやゴムの集成材、ベニヤ板やコンパネ、ラワンなどの合板と、いろいろな種類があります。それぞれ強度や加工しやすさ、見た目や質感、適した用途などが異なっているため、そのへんを考慮せずにサイズと価格だけで購入するとあとで困ったことになることもあります。

この中でおそらく一番難しいのは無垢材で、しっかり乾燥されたもの以外では含有水分の変化によって反りや割れなどが出ることもあります。また、枝打ち後の節目などがあると加工も厄介になってきます。ただ、一枚板の美しさは比肩しうるものはなく、高級テーブルや家具、寿司屋のカウンターなどなど、趣を重視する用途に向いています。

集成材は板材などを接着剤で加圧接着して作った材料で、無垢材に比べて反りや割れが出にくく、また比較的強度も安定している上に節目がないため加工しやすいことが挙げられます。ただ、場合によっては集成加工の分だけコストが高いものもあります。

合板はピンからキリまであり、コンクリ床の養生のために敷くような「とにかく直接傷つけないためのクッション」にするようなものから、安価な家具などに利用される化粧合板、またコンクリート型枠に使われるコンパネなど、様々です。木目(繊維方向)を縦横に組み合わせるなどして強い強度を持つものもあります。

SPF材と呼ばれるのは、スプルース(米唐檜(トウヒ))、パイン(松)、ファー(もみ)の板材で、この3種は色、見た目、特性などが近いためにひとまとめにして売られているものです。ホワイトウッドとも呼ばれています。主にツーバイフォー加工されていて、インチ単位の板材になっています。サイズ規格を揃えれば加工や組立などが楽になりますし、素材としても比較的やわらかくて加工がしやすいようです。ただし、やわらかい分腐朽は早いようで、雨ざらし(フェンスやウッドデッキなど)ではすぐに腐ってもろくなる、きのこが生えるなどの欠点もあるようです。

いわゆるツーバイ材で丈夫なのがレッドウッドで、さらにこれに防腐処理を施した防腐レッドウッド材というのもあります。ホームセンターでも置いているところはあまり多くないですが、耐候性、耐久性に優れ、ウッドデッキなどの屋外環境に適しています。が、ホワイトウッドに比べて表面ががさつく、枝払いが雑なためか節が多い、色味があまりきれいじゃないなどの特徴もあり、家具などには向かないようです。
レッドウッドを置いているところでは、3F(910mm)や6F(1820mm)よりも8F(2440mm)のほうが割安になります。必要なサイズを、切り代を加えて計算し、最適な長さを選べばよいでしょう。あまり長いと車で運ぶのも大変ですが、ホームセンターの工作室で予め切り代を加えて切ってもらえば楽ちんです。その後、自分でカットすればいいでしょう。

MDF材は中密度繊維板(Medium Density Fiberboard)という名が示すように、木材を繊維に分解してから樹脂で固めたものです。木材を繊維にして利用するため、リサイクルされた建材なども使われます。耐湿性などはあまりないと考えたほうがよく、加工のしやすさなどから主に家具などに使われます。その特性上、反りや割れはほとんどなくて材質も均質です。当然ながら木目はありませんが、かなり分厚いものも製造できるため、スピーカーなどの防振かつ重量のあるものにも向いています。

OSB材は配向性ストランドボード(Oriented Strand Board)で、アスペンなどの木を薄く削ったものを向きを揃えずに重ねたものを熱圧接着したものす。家屋の廃材や間伐材、強度がないために加工しづらい木材なども利用できるため安価で、また構造的にも強度は高いです。カット面は積層模様が特徴的です。ただし吸湿性があるため、場合によっては防水処理なども必要です。

サイズについてですが、現在ホームセンターなどで入手しやすいのは2x4(ツーバイフォー)材でしょうか。
日本ではもともとは木材の大きさは尺や寸で決まっていて、既存の建築物も寸法単位はメートル法で図面などは引かれますがベースとなっているのは尺や寸です。例えばベニヤ板やコンパネのサイズは1800mm×900mmあるいはそれよりちょっとだけ大きい数値ですが、これは3×6(サブロク。もともとは3尺×6尺)がベースとなっています。
一方、米国などでは現在でもヤード(インチ)、ポンド、ガロンなどが使われていて(ヤード・ポンド法)、2x4材は実は2インチ×4インチの木材、という意味です。
1インチは25.4mmですから、2x4材は本来ならば 50.8mm×101.6mmのはずですが、実際にはその後の木材の乾燥でサイズが縮むということから、その通りではないようです。さらに、1×1材は19mm×19mmですが1×4材は19mm×89mmで、19の倍数というわけでもないようです。ですので、よく使うサイズは覚えるしかないでしょう。
一方長さの方はワンバイ材、ツーバイ材ではフィートを使っています。尺貫法の尺は1尺30.303cm、1フィートは30.48cmとほぼ同じなので、これは非常にわかりやすい。だいたい1820mmや920mmとして売られています。両端は運搬などで傷ついたりすることもあるため、使用時に切り落としたとしても尺をベースに考えれば間に合います。

winsxs内のファイルの削除。

いまさらですがちょっと興味深かったのと、VirtualBoxで飼っているWindows 7のディスク容量がピンチになってきて調べてみたら\Windows\winsxs ディレクトリが10GB以上食っていたのでこれをどうにかしたいと思ったのとで、ググってみました。

「ディスクのクリーンアップ」で削除できるよ、という情報はMicrosoftの大きな Windows コンポーネント ストア (WinSxS) ディレクトリが原因で発生するディスク領域の問題を解決する方法にもあったのですが、どうやらこの10GBはこの方法ではだめみたいでして。

もうちょっとググったら、TechNetのほうにShould you delete files in the WinSXS directory? And what’s the deal with VSS?という記事を見つけました。

===
One of the common threads I noticed in my recent web trolling was the question “Can I delete the \Windows\Winsxs directory to save space?”.

So, to answer the question, the answer is simply: No.
===
(ちょっとBloggerの blockquote があまりにもアレなので、===で代用しています。ほんとはCSSいじればいいんですけど…)

基本的には手動で削除するのはだめ、だそうです。が、

===
Why? Because the component store (\Winsxs) is needed to repair the OS binaries in the event that a file becomes corrupted or, in worst case scenarios, compromised. There are a few directories in the component store so let’s look at them and what their general role is in Windows.

  1. \Winsxs\Catalogs: Contains security catalogs for each manifest on the system
  2. \Winsxs\InstallTemp: Temporary location for install events
  3. \Winsxs\Manifests: Component manifest for a specific component, used during operations to make sure files end up where they should
  4. \Winsxs\Temp: Temp directory used for various operations, you’ll find pending renames here
  5. \Winsxs\Backup: Backups of the manifest files in case the copy in \Winsxs\Manifests becomes corrupted
  6. \Winsxs\Filemaps: File system mapping to a file location
  7. \Winsxs\: The payload of the specific component, typically you will see the binaries here.

So, can you delete these? Sure, you could I guess. What would happen? Well, it depends. So long as the files in the \Windows\System32 directory are valid, most likely you wouldnt see any problems initially, the machine would “most likely” operate properly. However, the first time you attempt to update a binary, apply a service pack or service a component, it’s going to fail because the backing components needed arent there. The way the files end up in \System32 are via hardlinks. This should help answer another common question I see regarding how VSS is used in servicing. Short answer: It’s not. We use NTFS hardlinks to project the file to the file system from the component store. That’s why the \Winsxs directory is so important. The files there can be seen as the “authoritative” versions on the file system. When you encounter an issue and that binary needs to be replaced, running an SFC /SCANFILE against it will check the directories above and if the version doesnt match, it will re-project it so that its working.
===

意訳すると、
「コンポーネントストア(winsxs)はOSの修復のために必要だから削除できません。コンポーネントストア内にはいくつかのディレクトリがあるので、その役割を見てみましょう。
  1. \Winsxs\Catalogs: システム内のマニフェストごとのセキュリティカタログを含む
  2. \Winsxs\InstallTemp: インストール時の一時使用
  3. \Winsxs\Manifests: 特定のコンポーネントのマニフェスト
  4. \Winsxs\Temp: Tempディレクトリ、いろいろな用途に使われる
  5. \Winsxs\Backup: \Winsxs\Manifestsにあるファイルが壊れたときのためのバックアップ
  6. \Winsxs\Filemaps: ファイルの場所へのファイルシステムマッピング
  7. \Winsxs\: 特定のコンポーネントのペイロードで、通常はバイナリファイルがある

では、削除できるか?ええ、できます。何が起こる?場合によります。削除しても最初のうちは通常通り動いているように見えるでしょうが、バイナリのアップデートやサービスパックなどを当てようとしたときに、必要なファイルがそこにないからです。\system32にあるファイルはハードリンクなので。

だそうです。つまりはSystem32にあるファイルはwinsxs以下にあるファイルへのハードリンクなので、winsxs内のファイルを削除したあとで一見正常に動作しているように見えても、実はダメダメな状態になってしまっているよ、ということのようで。

でもアップデートされたあとの古いバージョンはちゃんと削除してほしいなぁ。

Bloggerの各記事に日付を入れたい。

どなたか知ってる人いませんかー。

LibreOffice Calcで為替レートを取得する。その4

マクロセキュリティの設定を「中」にすればマクロの実行ができることを確認できたので、為替レート(USD-JPY)の取得をマクロとして登録してみます。

その1で書いた次のコードをベースとします。

import urllib.request
import re

f = urllib.request.urlopen('https://info.finance.yahoo.co.jp/fx/convert/?a=1&s=USD&t=JPY')
s = f.read().decode('utf-8').split('\n')
for l in s:
    if 'price noLine' in l:
        jpy = float(re.search('[0-9\.]+', l).group())
        print(jpy)

やり方としては、unoモジュールをインポートしてドキュメントオブジェクトを作成し、そのオブジェクトのシートのセルを指定して書き込む、ということになります。

ところでunoモジュールとは何でしょうか。Python Guide - Introductionに説明がありました。

What is PyUNO?
LibreOffice has the ability to write macros in several interpreted languages, one of them is Python. PyUNO is the component that gives us access to the application programming interface (API hereinafter by its acronym Application Programming Interface) of LibreOffice with Python.

簡単に言えばPythonからLibreOfficeにアクセスするためのAPI、だそうです。LibreOfficeの関連では直接このPyUNOを説明しているものはないようですが、その前身となったOpenOffice.orgのほうにPyUNO bridgeとしてありました。でもかなり古いです。一番下のところに "このページの最終更新日時は 2010年3月28日 (日) 23:06 です。" なんて書いてあります。さらにそのページからダウンロードできるアーカイブには、"Last updated \$Date: 2007/11/26 19:36:55 \$" なんてあります。

ということは実際には "C:\Program Files\LibreOffice\program\uno.py" を読まなければわからないということでしょうか。
uno.pyをpydocに処理させてみたのですが、詳しいことは書いてありませんでした。あとはサンプルを見ろよ、ということかしら。
とりあえずやってみましょう。

import uno
import urllib.request
import re

def get_usd_jpy():
    doc = XSCRIPTCONTEXT.getDocument()

    f = urllib.request.urlopen('https://info.finance.yahoo.co.jp/fx/convert/?a=1&s=USD&t=JPY')
    src = f.read().decode('utf-8').split('\n')
    for line in src:
        if 'price noLine' in line:
            rate = float(re.search('[0-9\.]+', line).group())

    cell = doc.Sheets[0]['A1']
    cell.setValue(rate)
    return

これをLibreOffice Calcのマクロに登録します。


そして実行すると…。

できてしまいました。え?いや、もっと手こずるかと思ったんですが…。

となると、あとは体裁を整えるというか、"ドル円レート | (レート) | 2018年10月20日 12:00現在" みたいな感じで入れてやればいい感じになりそうです。

import uno
import urllib.request
import re
from datetime import datetime 

def get_usd_jpy(dummy):
    doc = XSCRIPTCONTEXT.getDocument()

    f = urllib.request.urlopen('https://info.finance.yahoo.co.jp/fx/convert/?a=1&s=USD&t=JPY')
    src = f.read().decode('utf-8').split('\n')
    for line in src:
        if 'price noLine' in line:
            rate = float(re.search('[0-9\.]+', line).group())

    now = datetime.now()
    doc.Sheets[0]['A1'].setString('ドル円レート 1USD=')
    doc.Sheets[0]['B1'].setValue(rate)
    doc.Sheets[0]['C1'].setString('円 {}年{}月{}日 {}時{}分現在'.format(now.year, now.month, now.day,now.hour,now.minute))
    return

2018/11/21 ソースコード改定 関数に引数を設定しないとエラーが出るようになったためdummyを追加。

ここで注意しなくてはいけないのは、ASCII文字以外(日本語とか)を書くときには文字コードをUTF-8に指定しておく必要があることです。


ということでできました。

あとはこのセルを参照するような使い方をすればいいでしょう。

本音を言えば、ワークシートを開いたときに自動でアップデートできるとか、あるいはボタンを配置してそれをクリックするとアップデートできるとか、そんな風にしてもいいかなとは思いますが、とりあえず目的は達成できました。

LibreOffice Calcで為替レートを取得する。その3

LibreOffice Calcで"Hello, World!"する続きです。

"LibreOffice Calc Python tutorial" でググってみると、Python Guide - My First Macroというページが見つかりました。ここにCalcでPythonを使う最初の一歩が書いてあります。

import uno

def my_first_macro_calc():
    doc = XSCRIPTCONTEXT.getDocument()
    cell = doc.Sheets[0]['A1']
    cell.setString('Hello World in Python in Calc')
    return

そのページにあるWriter用のプログラムと比べてみると、uno モジュールを import して doc オブジェクトを作るところまでは一緒ですね。
違いは6行目からで、doc オブジェクトの getText()を呼ぶとWriter、Sheetsを参照するとCalcになるんでしょうか。

Calcの6行目では "Sheets" オブジェクトの "[0]" で参照されるシートの "A1" セルをcellオブジェクトとして作成し、そこに7行目で setString() を用いて文字列を入力しているようです。

ということは…あれ、もうできちゃいましたか?


これを保存すると、先ほどのマクロマネージャーに "HelloWorld" が登録されました。


ここでこの "HelloWorld" を実行すると、A1セルに文字列が入りました。おめでとう。

ひとつ注意しなくてはいけないのは、ここで登録されたように見えてこのPythonプログラム(マクロ)はテンポラリディレクトリに保存されているという点です。つまり、この 無題1 ドキュメントを閉じてしまうとその時点で消えてしまいます。
マクロはCalcのファイル内に保存されるため、無題1 を保存すればマクロも一緒に保存されます。が、次にそのファイルを開くと、「セキュリティ上の理由からマクロは実行できません」というメッセージが出ます。



…むむぅ。これでは意味がありません。でも、セキュリティ上やむを得ない部分もあるのは理解できます。

かつてMicrosoft Office上で動作するマクロウィルス "Melissa"(Wordマクロ)とか "laroux"(Excelマクロ)が世界を恐怖のズンドコに突き落とした事例がありました。そのため、基本的にマクロの実行機能はデフォルトでは禁止という形になっているわけです。

ではどうすればいいか、ですが…。

方法の1つは、LibreOffice Calcで為替レートを取得する。その2で設定したマクロセキュリティ設定を「中」にすることです。


ここを読むと、「中」の場合にはマクロの実行前に確認が求められるとあります。これを選択することで、マクロ実行時に確認は求められるものの、実行できるようになります。具体的には、ファイルを開いたときに「マクロがあるけどどうしますか?」と訊かれて「マクロの有効化」か「マクロの無効化」を選択します。マクロを有効化すれば、Pythonマクロは実行できるようになります。

一方「高」の場合には「署名のないマクロは無効になります。」とあります。逆に言えば、ファイルに署名がしてあれば実行できるということでしょう。
ともあれ、一旦はマクロセキュリティレベルを「中」にすればPythonマクロは実行できることがわかりました。

LibreOffice Calcで為替レートを取得する。その2

PythonでYahoo!ファイナンスからその時点での為替レートを取得することはできたので、次はLibreOffice Calcからそのデータを利用する部分です。
が、Calcの「ツール」→「マクロ」→「マクロの管理」→「Python」というメニューがありますが、そこではPythonマクロ(プログラム)の実行はできても、追加や編集はできないようです。

ググってみると、考えるエンジニアさんのLibreOffice CalcでPythonマクロを使う(2)にまとめられていました。

まず、LibreOfficeでPythonをマクロとして登録して使うための機能拡張 APSO(Alternative Script Organizer for Python)をダウンロードしてインストールします。APSOはLibreOfficeにPythonを組み込むマクロ管理拡張です。
インストールするには、ダウンロードした "apso.oxt" をダブルクリックすればOKです。

次に、「ツール」→「オプション」の設定ダイアログを開きます。


「セキュリティ」を選択し、「マクロセキュリティ」をクリックします。
「セキュリティレベル」タブでは、セキュリティレベルは「高」のままにします。「信頼されたソース」のタブで、「信頼されたファイル位置」に先ほど作ったPythonプログラムの保存場所を登録します。自分はGoogle Driveの中によく使うライブラリ用のフォルダを用意しているので、そこに "LibreOffice\Python" というディレクトリを掘りました。その他のCADなどで使用するライブラリもここに収納しています。


これでこの場所にあるPythonスクリプトを登録できるようになりました。

次に、APSOで使用するエディタの登録を行います。
「ツール」→「拡張機能マネージャー」を開き、「APSO」を選択して「オプション」をクリックします。


すると、"EditorKicker"の項目にエディタの設定ができるようになっているので、使い慣れたエディタを指定します。ここでは "秀丸エディタ" を指定しています。


これで設定などの準備は整いましたので、「ツール」→「マクロ」を見てみると、"Organize python scripts" という項目が増えています。早速なにかやってみましょう。この "Organize..." をクリックします。


まず、無題1を選択して、「Menu」→「Create Module」をクリックします。


するとモジュール名を入力するダイアログが現れるので、試しになにか入れてみます。


まずはCalcのセルになにかを表示してみたいので、定番の "Hello, World!" をやってみます。すると "無題1" の下に "Hello, World!" ができてくるので、それを選択してから「Menu」→「Edit」します。先ほど設定したエディタでソースが開かれます。


ファイルのパスが "AppdData\Local\Temp" 以下にあるんだけれど大丈夫かしら…。

さて、Pythonではなにかをするためにはまず対応したモジュールを import して、そこから関数やオブジェクトを利用するという形になるわけですが、当然Calcになにかを入力するためにはCalcのAPIを叩くモジュールが用意されている…ハズ…されてるといいな。

ちょっと長くなってきたのでその3に続きましょう。

LibreOffice Calcで為替レートを取得する。その1

仕事や趣味で基板のコストを計算するのに、海外から輸入するような部品の場合には為替レートが必要になります。大きい会社では代理店などを通じて見積もりを取ればいいんですが、小さい会社や個人でやるような場合にはそうはいきません。

当然ながらコスト計算なので表計算ソフトを使用するわけですが、ここではLibreOffice Calcを使っています。

今のところCalcでは、外部の為替レートを表示してくれるサイトからページを読み込んでワークシートに配置し、その中から現在の為替レート(USD-JPY)を含んだセルを参照して加工し、数値に変換して計算に使うということをやっています。

が、もうちょっとカンタンに取得できる方法はないかなぁと。

まずは "1USD" でぐぐってできるだけ単純そうなのを探します。すると、Yahoo!ファイナンスのところがわりあいシンプルなので、ちょっとソースを眺めてみます。すると、

<!-- fxHeaderTtl -->
<h1 class="fxRateCalTtl">為替レート計算結果</h1>

<!-- fxRateCal -->
<div class="fxRateCal">
<table class="fxRateTbl">
    <tr>
        <th>コード</th>
        <th><span class="icoCenter icoCUsa18">アメリカ ドル</span></th>
        <th>最新取引レート</th>
        <th class="noLine"><span class="icoCenter icoCJpn18">日本 円</span></th>
    </tr>
    <tr>
        <td class="code"><a href="https://rdsig.yahoo.co.jp/finance/fx/convert/result/RV=1/RU=aHR0cHM6Ly9zdG9ja3MuZmluYW5jZS55YWhvby5jby5qcC9zdG9ja3MvZGV0YWlsLz9jb2RlPVVTREpQWT1Y">USDJPY=X</a></td>
        <td class="from">1</td>
        <td class="newest">112.360000<span>(12:39)</span></td>
        <td class="price noLine">112.36</td>
    </tr>
</table>

なんて感じになっていて、下の方にある class="price noLine" を引っかければなんとかなりそうかな、と。
試しにコンソールから叩いてみます。

$ curl -s "https://info.finance.yahoo.co.jp/fx/convert/?a=1&s=USD&t=JPY" | grep "price noLine"
        <td class="price noLine">112.33</td>
$

これならわりと簡単に行けそうな気が…。

LibreOfficeはPythonも一緒にインストールしてくれています。現在のLibreOffice 6.0.6には、Python 3.5.5が組み込まれています。そして標準ライブラリとしてurllibなども一緒に組み込まれているため、余分なものをインストールせずに利用できそうです。

import urllib.request
f = urllib.request.urlopen('https://info.finance.yahoo.co.jp/fx/convert/?a=1&s=USD&t=JPY')
f.read().decode('utf-8')

とすると、ちゃんとHTMLソースをリトリーブしてくれるようです。

なのでプログラムを書いてみます。


import urllib.request
import re

f = urllib.request.urlopen('https://info.finance.yahoo.co.jp/fx/convert/?a=1&s=USD&t=JPY')
s = f.read().decode('utf-8').split('\n')
for l in s:
    if 'price noLine' in l:
        jpy = float(re.search('[0-9\.]+', l).group())
        print(jpy)

これを実行すると、

$ python \Users\kats\Desktop\get_jpyusd.py
112.45

と、2018/10/19 14:35現在のレートが取得できました。

このプログラムを get_jpyusd.py として保存しておきます。

あれれ、このPythonプログラムをどうやって登録するんだろう。ということで、続きます。

ftpアプリについて。

外部からおうちサーバのファイルを参照しようと思ったので、ftpクライアントアプリを検索してみました。

窓の杜で、FFFTPとかWinSCPとかが表示されてきて、思わず懐かしさがこみ上げてきたり。

FFFTP、まだ開発継続してたんだ、ありがたや、と思ったんですが…さすがにscpには対応していないようで、代わりにftpsという設定項目がありました。SSLでftpするということのようで、利用するためにはおうちサーバのProFTPDの設定を追加する必要があります。ポートも違うし。

一方のWinSCPはSSH上でのファイル転送を行うものです。SCPによるファイル転送は、TTSSHでもファイルメニューから "SSH SCP" という形で呼び出せます。

という周辺知識は置いといて、今回FFFTPをインストールしてみたんですが、やっぱり生でパスワードが流れるのは好ましくないですし、他に手段はないかなぁと思ったところ、「あれ、もしかしてRLoginでできたりするんじゃ…」と。

早速RLoginでおうちサーバにSSH接続して、ファイルメニューを見てみると、"SFTPファイル転送" の項目がありました。RLoginすごい。すでにSSHで繋いでいるので、新たにコネクションを張る必要もないですし、2ペインのFFFTPライクな画面でファイル選択もカンタン。必要なファイルをドラッグ&ドロップで取得できます。

ボール盤のチャック外し

チャックが固着して外れなくなっているので、ちょっと忘れないようにメモです。

  • ボール盤: KIRA NSD-13
  • Vベルト型番: A41 (取説ではA39となっているが計算するとA41になるのでちょっと謎)
  • ジャコブステーパー: JT6
  • チャック: 13MG
  • 深さ調整ストッパ: ネジ径 12.6mm、16山/インチ
  • チャックが固着している場合、チャックドリフト(株式会社堀内製作所)があれば、両側からクサビを少しずつ打ち込めば抜けるらしい。ただ、これだけで結構な値段するので、スパナなどをかませてハンマーで下向きに叩く、こじるなどしてチャックをずらしていく方法もあるし、どうやらバーナーでチャックを炙って外しやすくする方法もあるらしい。
  • チャック交換時はスピンドルの油やグリスは徹底的に落としておくこと。
  • ちなみに上記チャックドリフトと同様のものが、Chuck Wedges setsとしてAMAZON.COMやeBayで出てる。"jacobs taper wedges chuck jt6" あたりを検索ワードにすると、結構いろいろ出てくる。米国からだと送料がだいたい20ドルくらいかかるけど、上記チャックドリフトよりも安い。
です。

深さ調整ストッパのネジ規格が謎です。インチネジで12.6mm径だとユニファイ並目で13山、ユニファイ細目で20山が規格なので。16山だと、ナット一回転で25.6/16=1.6mm移動します。0.8mmなら0.5回展、0.5mmならほぼ1/3回転、1mmなら2/3回転弱というところでしょうか。でもナットを1/3だけ回すのはムツカしそう。

Vベルトがぼろぼろになっていたので新品に交換したんだけれど、やっぱりA39で正しかったみたい。A41でモーター位置を調整してテンションかけたけれど、若干弛みがあるし。

ふと思ったんだけれど、自転車用のコッタレス抜きは使えるんだろうか。今度見てみましょう。

追記:
いくつかチャックウェッジ(チャックくさび)探してみたんですが、アメリカのAMAZONが国際発送してくれるようです。モノはこれ。ちょっと時間はかかりますが、商品価格が11.93USD、送料が 8.29USD(Amazon Global Expedited Shipping)で6-10 business daysでの配送を選択しました。合計で20.22USD、日本円で2,358円。上に書いたよりも安く入手できそうです。
以下に進捗をメモです。以下でfacilityとは施設のことなので、配送センターとか倉庫とかそんな感じです。

  1. 2018年10月18日に注文。
  2. 11月2日にデリバリ予定のメール到着。
  3. 10月19日、荷物が出品会社を出発。
    (Package has left seller facility and is in transit to carrier)
  4. 10月20日にも11月2日に到着だよ、とのメールが届く。
  5. 10月20日、ケンタッキー州ヘブロンに荷物が到着。
    (Shipment arrived at Amazon facility Hebron, KENTUCKY US)
  6. 10月21日、ケンタッキー州ヘブロンを出発した模様。
    (Shipment departed from Amazon facility Hebron, KENTUCKY US)
  7. 10月21日、ニュージャージー州アヴェネルに到着。
    (Shipment arrived at Amazon facility Avenel, NJ US)
  8. 10月22日、アヴェネルを出発。
    (Shipment departed from Amazon facility Avenel, NJ US)
  9. 10月22日、配送会社に荷物が到着。
    (Package arrived at a carrier facility)
  10. 10月24日、配送会社から荷物が出発。
    (Package has left the carrier facility)
  11. 10月26日、通関手続き開始。
    (Initiated customs clearance process7:00 AM)
  12. 10月27日、通関手続き開始。
    (Initiated customs clearance process 4:34AM)
  13. 10月27日、通関手続き完了。
    (Completed customs clearance process 5:10AM)
  14. 10月30日、出荷済み。
    (Out for delivery 9:18 AM)
  15. 10月31日、到着

26日と27日にそれぞれ通関手続き開始のメッセージが謎です。27日に通関手続きが終わって、30日に "Out for delivery" とありますが、まだ日本には到着していないでしょうから出荷済みでしょうね。まさか配送中持ち出しではないでしょうから。

と思ったら、10月31日に到着しました。早い。

早速使って見ましたが、片方をしっかり奥深くまで差し込んでおいて、もう一方を反対側から入れます。このとき、くさびの斜面となっている部分がお互いに向き合うようにして、くさびが必ず平行に入っていくようにします。
チャックが落ちても衝撃が加わらないように下にクッションを用意してから、ハンマーでくさびを打ち込んでいきます。このとき、チャックを手で受け取ろうとすると受け取りそこねて傷つけてしまうこともあるので、キャッチは下のクッションに任せます。

結果ですが、簡単に外すことができました。検索するとガストーチで炙ったりレンチをかませて叩いたりという記事も見つかりますが、2000円ちょっとなら米アマゾンで買うのもいいのではないでしょうか。

PROXXON No.27150 クロステーブル購入。

ボール盤で簡易フライス加工したくて、テーブルへの固定とか深く考えずにとりあえずPROXXONのクロステーブルを購入してみました。



あきばお~楽天店で税込み12,187円。価格としてはかなり安いと思います。PROXXONのページだと上代が22,000円ですし。
本来4~7日で届くというところ、稼働日のみで10日(休み入れるとまるまる2週間)かかりましたが、無事届きました。ちゃんと新品だし、梱包もOK。マニュアルその他一式、ちゃんと揃ってます。

ということで早速取り出して眺めてみます。

テーブルトップには傷防止の青いビニールが貼ってあります。実際に使うときまで剥がすのはやめておきますが、フライス盤で平面加工した跡が透けて見えます。曲尺を当ててみると平面はそれなりに出ていて、ひと目で分かる隙間などはありません。裏面も同様に見ましたが問題なし。

次にハンドルを回してみますが…渋い。というか重い。あまりにも重たくてハンドルがうまく回りません。これ、重すぎてスムーズに動かないしテーブルに余計な力が加わるからフライス加工がガタガタになるあかんやつでは…。付属の説明書を見ると、サイドにある調整ネジは調整済みだそうですが、何を調整したのやらと疑いたくなる感じです。なのでいきなり分解。

ガタツキと動作のスムーズさのバランスは、調整ネジでアルミ板を対抗レールに押し付けて行っています。まず調整ネジを緩めるために、2mmのヘックスレンチと7mmのスパナを用意し、全部のネジを緩めます。この時点でだいぶ軽い感じになっています。
構造上、上テーブル(画像右手のハンドルでY軸方向)は簡単に外れますが、下テーブル(左手のハンドルでX方向)は外れないようになっています。たぶんハンドルをばらしてリードネジを抜けば外れるかもしれませんが、今回はそこまでやりませんでした。

テーブルを分解したので、AZの二硫化モリブデングリス(蛇腹入り)で摺動面をグリスアップ。結構粘度があるので絞り出すのにちょっと力が必要でした。今度、AZのチッコイグリスガンでも用意しましょう。このAZのグリス、ドイトで蛇腹40gで88円と安かったので買ってきました。余談ですが、自転車のハブなどのベアリング部分に使うなら、AZのリチウムグリスあたりがよさそうです。ちなみにデュラエースグリスはカルシウム石鹸系だそうです。グリスアップし直す場合には、以前のグリスをパーツクリーナなどで完全に落としてからにしましょう。

さて、蛇腹から絞り出して指でぬとーっと塗り拡げ、アルミ板をセットしてテーブルを組み直します。念のためハンドルの軸受部とシャフトネジ部分にも塗っておきます。

調整ネジを締めない状態で回してみると…快適にスルスル動きます。ウソみたいにスルスルです。

次に調整ネジをちょっとずつ締めて、キュッと抵抗があるところから60度ほど戻し、ナットで固定。実使用していないから工作時のガタまではわかりませんが、快適に動きます。

ただ、シャフトが片持ちなためか若干ブレる感じがありました。もしかしたら将来CNC化するかもしれないし、そのときには両持ちにするか、精度のよさそうなリード2mmのネジに交換するか、安めのボールネジにするかというところでしょうか。

ファーム書き込みジグを作ってみる。組み立て編

さて、アクリル板の加工は無事…というか、思った以上にコストが掛かってしまいましたが終了したので、次は組み立てです。

ファーム書き込みジグを作ってみる。アクリル加工編では、左側の四角い穴の周囲に3ヶ所ほどφ3.2のマーキングがしてありますが、これはレーザー加工機の「彫刻」でマーキングした部分です。
ここにM3.2のドリルで止まり穴を掘って、別途買ってきたアクリル棒(φ3.0)を適当な長さに切ってはめ込み、基板をセットするときの固定ピンとする…予定だったのですが、さすが樹脂加工の悲しさ、φ3.0のアクリル棒がφ3.2の穴にハマりません。

ちなみに止まり穴は電動ドライバで掘ると簡単に突き抜けてしまいそうだったので、指で摘んでくるくると回しながら彫りました。このとき思ったんですが、センター穴くらいはφ0.5くらいでも開けておけばよかったかな、と。NACHIの鉄工ドリル用のビットで、ノギスで深さを測りながら約2mmほど掘りました。

で、棒の直径です。ノギスで測ってみたら、φ3.25くらいでした。それは入らないわ…。しかも微妙に真円ではない感じ。ついでに基板穴にも当ててみると、ぎりぎりです。基板のネジ穴は若干余裕を見てφ3.4で開けてたんですが…。

これだと、アクリル板の止まり穴をφ3.4ドリルで掘ったとしても基板がスッとはまらない可能性が高いです。なのでアクリル棒を補足してみることにしました。
サンドペーパーで回りを削ってひと回り小さくしようと思いましたが、手作業でやると均一に丸く削れません。なので文明の力を借りて電動ドライバに棒をセットし、#600のペーパーで先端部をつまんで削ることにしました。摩擦熱で熱くなるので要注意。

ときどき穴にはめ込んで太さを確認しながら研磨していくと、わりとカンタンにいい感じに削れました。

次に棒を5mmに切ります。これは方眼カッティングマットの目盛りに棒の端を合わせ、5mmの位置にカッター刃を強めに当てて、棒をくるりと一周転がして切り目をつけます。先端部をペンチでつまんで折り曲げると、カンタンに5mmのピンができあがります。

このピンにちょびっと接着剤をつけて穴にはめ込みます。ここでは手元にあったセメダインスーパーX2 超多用途速硬化タイプを使用しました。


ここに基板をセットしてみると、いい感じにスッとハマります。


こんな感じ。ピンもちゃんと基板のネジ穴に通っています。

ただ、今回レーザーでカットしてみて最終的に思ったのは、やっぱりコストが悪すぎるということです。当然、何度かやってみてデータ作成からオペレーションまでさっさと自分でできるようになればいいのだとは思いますが、絵や写真を彫刻する、というような用途ではなくてこういうカットだけみたいな目的で使うのであれば、電動卓上糸ノコ(ジグソー)で切ったほうがコスト的には遥かに安上がりです。しかもカインズホームのDIY工房なら無料で利用できますし。ジグソーでも直線ならレールを当てて切れば十分に真っ直ぐな線が切れますし。
あるいはフライス盤があるならそちらでもいいかもしれません。

ファーム書き込みジグを作ってみる。CADデータ編

FreeCADとInkscape、Illustratorの連携でちょっと腑に落ちない点があったので調べてみました。

ちなみに使用しているソフトのバージョンは以下のとおりです。

  • FreeCAD: 0.17.13541
  • Inkscape: 0.92.3
  • Illustrator CC: 2018 22.1 (64-bit)

まず、Inkscapeで面付けしたデータをエディタで見てみます。

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="320mm"
   height="180mm"
   viewBox="0 0 320 180"
   version="1.1"
   id="svg8"
   inkscape:version="0.92.3 (2405546, 2018-03-11)"
   sodipodi:docname="ProgStage.svg">

最初の部分にアプリの情報とワークサイズが指定されています。

次にデータ部分を見てみると、

<path
       inkscape:connector-curvature="0"
       style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:0.00035278;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
       d="M 157.055,206.73217 H 41.054987 v 0 z"
       id="Cut055_f0000" />

ちょっと右の方に長いですが、この中で "stroke-width" というのが線幅の指定のようです。かなり細かい数値になっていますが、調べてみると 1pt=25.4/72 (mm) = 0.35277777777777775 mm という値をベースとして、0.001ptなのでその1000分の1という数値になっているようです。

次にこのSVGファイルをIllustrator CCで読み込んで、別のSVGファイルとして保存して中身を見てみます。

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1"
  id="svg8" inkscape:version="0.92.3 (2405546, 2018-03-11)" sodipodi:docname="ProgStage.svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg"
  xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 907.1 510.2"
  style="enable-background:new 0 0 907.1 510.2;" xml:space="preserve">
<style type="text/css">
 .st0{fill:#FFFFFF;stroke:#000000;stroke-width:3.527800e-04;}
 .st1{fill:#FF0000;stroke:#FF0000;stroke-width:3.527800e-04;}
 .st2{fill:#FF0000;stroke:#FF0000;stroke-width:3.527800e-04;stroke-opacity:0.7067;}
</style>

同じファイル形式なのにずいぶんと違っていますが、styleのところを見ると、.st0が黒の線、.st1が赤の線、.st2が赤の線らしいことがわかります。
そして実際のデータは、

<path id="Cut055_f0000" inkscape:connector-curvature="0" class="st0" d="M445.2,371.4H116.4l0,0H445.2z"/>

と、class="st0" が指定されていることがわかります。多分これは黒線でしょう。その他のデータをよく見ると、赤の円が2つはst1、1つがst2で指定されていることがわかりました。なんでこんなことになっているのかは不明ですが。
そしてすべてのオブジェクトは必ずclass指定があって、st0~st2の値がつけられていました。

Inkscapeで出力したSVGファイルをIllustratorで読み込むと、アピアランスに表示される線幅が0になっているように見えたのですが、どうやらデータとしては残っているようです。一応安心です。

追記:
ところで、試用版を使っていたAdobe Illustrator CCですが、試用期間終了のお知らせが来ました。
今すぐご購入を、というので価格を見てみると、単体プランで年一括26,160円。仕事や趣味で毎日使うならありかもしれませんが…年に数えるほどしか使わないレベルだと、この価格は正直ありえません。なのでさくっとアンインストールすることにしました。

ファーム書き込みジグを作ってみる。アクリル加工編

さて、データができたのでカインズホームのDIY工房に持ち込んで加工編です。

結論から言うと、とてもすばらしいデキで加工ができました。

ただし、後でまとめますがいくつかツマヅイた点があり、時間がかかってしまったために延長料金になってしまいました。
ちなみにレーザー加工機の使用料は20分で1,500円。延長が45分まで1,500円。なので結局、簡単な加工なのに3,000円もかかってしまいましたが、勉強代としておきましょう。次の機会にはちゃんと今回の失敗を反映してサクッとやりますよ。


上の写真では、まだアクリル表面のカバーシートは剥がしていません。カットラインは非常になめらかで、美しく仕上がっています。

時系列でツマヅキポイントを整理してみます。

  1. データを持ち込んだUSBスティックが読めなかった。
    このために一旦家に戻ってやり直ししました。何がいけなかったって、USBスティックの中でパーティション切っていたこと。もともとManjaro LinuxをインストールするためにISOイメージとEFIを焼いてあったUSBスティックの空き部分をFAT32ボリュームにして、そこにデータを入れていったんですが、カインズのPCではそのFAT32ボリュームを認識してくれなかったのでデータ自体が読み取れなかった、ということです。
    教訓その1: USBスティックでデータを持ち込む場合には、パーティション構成に気をつけて必ず1ボリュームのみにしましょう。
  2. データのパス(線)の太さが間違っていた。
    これが今回一番引っかかったところです。FreeCADから "Flattened SVG" で出力してInkscapeで読み込むと、線の太さは0.35ptになるようです。が、今回のレーザー加工機ではその線の太さが0.001ptである必要があり、それ以外の太さの線は認識しないようです。
    これは現場で、すべての線を選択して0.001ptに変更してやっと動くようになりました。
    家に戻っていろいろと試してみると、Inkscapeで0.001ptを設定しても、Illustratorに読み込むと0ptになってしまうようです。
    教訓その2: SVGをIllustratorに読み込んだら、全選択して0.001ptに設定しましょう。
  3. データのパス(線)が二重になっていたため、レーザーが往復していた。
    FreeCADで3Dモデルから "Flattened SVG" に出力しましたが、もとが3Dのため、Z軸方向から投射した場合には上のエッジと下のエッジが重なって出力されます。当然その場合にはパスが2本重なっていますので、レーザーが2回カットすることになります。これは害にはなりませんが加工時間が倍になってしまいますので、レンタル時間が延びてしまう要因になります。
    データを作成するときには、線が重なっていないことを確認したほうがいいでしょう。
    教訓その3: パス(線)が二重になっていないか確認しましょう。
  4. 彫刻部分(止まり穴)を彫るのは難しかった。
    今回、基板の位置決めピン(φ3.0)を立てるための止まり穴をレーザーで彫れるかと考えていました。彫刻モードでならできるかな、と思ったのですが、このモードではせいぜいマーキング程度しかできないようです。出力を調整すればできるとは思いますがそのための時間が取れないため、現実的ではなさそうです。なので、レーザーでは精密な位置のマーキングだけにして、止まり穴自体はφ3.2の鉄工ドリルビットで掘ることにしました。
  5. 彫刻の塗りつぶし指定を忘れないこと。
    これは止まり穴のことですが、最初に輪郭の円だけ描いておしまいになっていました。これを同じ色指定で塗りつぶすことで、苑の中身までをしっかり彫刻してくれます。円だけだとちょっと色が薄いため、中身も彫刻してほしい場合にはしっかり塗りつぶしておきましょう。
  6. グループ解除について。
    グループ解除についてはよくわかりません。やったほうがいいのかやらなくても大丈夫なのか。今回は全部解除して行いました。が、レーザー加工機はプリンタとして使用する形になるため、SVG上のグループ指定は問題にならないように思います。心配な場合には解除しておけば間違いないでしょう。

以上のポイントをしっかり押さえておけば、Illustrator CCはSVGファイル読み込めますのでInkscapeでの編集でいけることがわかりました。

ファーム書き込みジグを作ってみる。アクリル設計編

仕事で設計している基板はPICマイコンを搭載していて、中国のPCBCartに製造(基板製造、部品購買、実装)をお願いしているんだけれど、納品された状態ではファームウェアが書き込まれていません。

なのでこちらで書き込む必要があるのですが、ICD3を使うにせよPICkit3を使うにせよ、数をこなすとなるとなかなか面倒です。アダプタつないで書き込みケーブルつないで、と。
そこで、アクリル板と金属スペーサーを使って書き込み用のステージを作ることにしました。

まず基板のサイズとアダプタのプラグ固定のためのスペースを見繕って、FreeCADで3Dモデルを作ってみます。

こんな感じ。


仕様は3mm厚のアクリル板で、サイズは80x120mm。下の板は金属スペーサー用の3.2φのキリ穴が4つのみで、四方の面取りだけしています。上の板はDCジャックを通す穴と、基板固定用の3つのピン。あとはサブ基板を裏に貼り付けてテスト用の金属プレートを貼り付けます。3つのピンは3.2φで深さ2mmの止まり穴をあけておいて、そこに3φのアクリル棒を5mm程度の長さに切ったものを接着剤で固定しようと考えています。

一応3D図面はできました。FreeCADではここから三面図などの2D図面に落とすのは少々手間がかかるのですが、今回は作るのは1台だけなので余計なことはしたくありません。アクリル板を買ってきて、ノコで切ってドリルで穴あけ…すればできるのはわかっているのですが、どうせならきれいに作ってみたい。

そこで、カインズホームのデジタル工房でレーザー加工機があったのを思い出しました。
データを持ち込めば20分1500円でやってくれるようです。さらにレーザー加工ならば、元データが正確ならばきちんときれいに加工できそうです。

利用方法を調べてみると、カインズで材料を購入してからデータをSDカードかUSBメモリで持ち込み、Adobe Illustrator CCを使ってデータ読み込み、線に色を付けてから色データと加工種類を関連付けて「印刷」とすればいいようです。

さらに調べてみると、ここで使っているレーザー加工機はtrotec Speedy300とのこと。彫刻、カット、マーキングができるようです。彫刻ができるなら止まり穴も開けられるかも。

ということで手持ちのツールでデータを作成できるかどうかを調べてみました。Illustratorはいわゆるドローツールなので、Inkscapeで同じことができるかもしれません。Inkscapeのデフォルトのファイル形式はSVGです。一方、FreeCADもSVGへのエクスポートは可能です。そしてIllustrator CCは体験版をダウンロードしてみるとSVG形式は読み込めるようです。こちらにも扱えるファイル形式の一蘭がありました。
つまり、こちらサイドではFreeCAD→Inkscapeでデータを作成しておいて、それをカインズに持ち込んでIllustratorで読み込めばうまくいきそうです。

まずはFreeCADで作成したプレートをSVGでエクスポートします。
部品はひとつずつ処理したほうが間違いがないので、まずは上プレートをやります。
Part ワークベンチで加工面を正面にして表示し、モデルを選択します。


その状態で "File" → "Export" → "Flattened SVG" を選択して出力します。同じことを下プレートでも行います。

次にInkscapeを起動します。
用紙サイズを設定しますが、カインズのオンラインストアで調べてみるとアクリル板のサイズは180x320mmが標準のようです。3mm厚ということだと、アクリルEX板001透明180x320x3ミリがよさそうです。ちょっと高い気もしますが。

Inkscapeで用紙サイズを320x180(横長)に設定し、先程出力したSVGファイルを並べます。ワークサイズが大きいので、ついでに下プレートをもう2枚取ることにします。何かで使えるかもしれないので。


上プレートはピンを立てるための止まり穴が3つあり、マニュアルでは彫刻部分の線の色を変えるように書かれています。なので上プレートを選択してグループ解除し、止まり穴の色を変えました。"ストロークの塗り"を選択して、RGB=255:0:0の赤を選択。


マニュアルではベクターデータにしろとあるので、一応すべてのオブジェクトのグループを解除しておきます。そうしたらこれを「アクリル板カット用.svg」という名称で保存しました。

次にこれをAdobe Illustrator CC体験版で読み込んでみます。


ちゃんと読み込めているようです。ただ、オブジェクトをクリックすると全部まとめて「パス」ということになっているようなので、右側のクイックメニューから「グループ解除」してみました。その状態で各パスの長さを見てみるときちんと設計通りになっているようなので、色を付けるところまでやっておけばあとはデータを持ち込んで読み込み→グループ解除でいけそうです。

早速明日やってみます。

Bloggerの投稿日付の扱い。

このブログを見れば一目瞭然なんですが、各投稿記事のところ、日付はなくてなぜか時刻のみになっています。
自分的感覚としては、投稿した時刻よりも投稿した日付のほうが重要だと思うんですが…なんでこうなっているのか。

ちなみに投稿時刻の上にマウスカーソルをホバーすると投稿日時がチップしますので、確認手段さえ知っていれば投稿日時を知ることはできますが、そこまでできるなら素直に表示してほしいところ。

ところがこれを表示するための設定項目というのがなくて、表示するためにはHTMLテンプレートをいじらないといけないようです。

ということでググって見るわけですが、引っかかってくるのは "data:post.dateHeader" を判定している部分を、判定をなくして "data:post.timestamp"を表示させればいいよ、というものばかり。ところがなぜか自分の使っているテーマではそもそも "data:post.dateHeader" を判定している部分がありません。

おそらくこちらの Show Date For All Posts in Blogger とか Bloggerで記事の公開日/最終更新日を表示してみた などがたぶん正解を示してくれているんだと思うんですが、なんか変。特に後者は2018年の記事なのに。
テーマを変更すると出てくるのかしら。

鉄製品の錆落とし。

錆びた鉄製品をサンポールに浸しておくと、赤錆がきれいに落ちる、という記事がけっこうあります。
ちょっとHTML記法的にどこまで表現できるかも含めて、化学式で表現してみます。

まず酸化鉄は酸化第一鉄(酸化鉄(Ⅱ))と酸化第二鉄(酸化鉄(Ⅲ))、それに四酸化三鉄(酸化鉄(Ⅱ,Ⅲ))などがあります。化学式はそれぞれ、FeO、Fe2O3、Fe3O4となります。
このうち、赤錆は酸化第二鉄、黒錆は四酸化三鉄が主成分です。錆びた鉄、という場合にはたいてい赤錆を指します。

産業的には赤錆はフロッピーディスクの磁性面に利用されたり、微粒子を装飾品やガラスレンズの研磨剤としても利用していたようです。現在でも研磨剤として使われていて、グラインダーなどで使用する赤棒は酸化鉄を使用しています。
余談ですが研磨棒は赤→白→青の順に粒度が上がり、白は酸化アルミニウム、青は酸化クロムが主成分になります(https://jp.misumi-ec.com/tech-info/categories/surface_treatment_technology/st01/c1981.html - MiSUMi-VONA 技術情報から)。


閑話休題。


赤錆は酸化第二鉄 Fe2O3 が主成分なのでこれをターゲットとします。一方サンポールは塩酸 HClが主成分です。なので、

Fe2O3 + 6HCl → 2FeCl3 + 3H2O

となるかと思いきやさにあらず。

実は赤錆はその主成分は酸化第二鉄ですが、実際には水和物として存在しているらしく、FeOOH(オキシ水酸化鉄)をもとに考えないといけないようです。別の書き方としては、Fe2O3・H2O となります。そのため、反応式は以下のようになるようです。

2FeOOH + 6HCl → 2FeCl3 + 4H2O

ですがこのとき水中では塩化鉄() FeCl3 はイオンとして遊離しているため、Fe3+ + 3Cl- となっているようです。

赤錆が溶け出した状態では主にこの Fe3+ が水中にありますが、ここに炭酸ナトリウム Na2CO3 を投入します。
すると鉄とナトリウムのイオン化傾向の差によって、

2FeCl3 + 3Na2CO3 → 2Fe↓ + 6NaCl + 3CO2

となって、二酸化炭素の泡が出て、溶けていた鉄が沈殿し、水溶液は食塩水になる、はずです。たぶん。なるといいな。

実際には赤錆以外の鉄も塩酸中に溶け出しているでしょうし、酸化第三鉄なども含まれているでしょうから、必ずしもこの通りになるとは限りませんが、大筋としての理解はこれでいいのではないかな、と思います。

ただし実際に実験する場合、サンポールを使うと塩酸以外の成分も含まれているので、ちょっと舐めてみるというのはやめたほうがいいでしょう。

それにしても、高校のときにも思ったけれど、鉄イオンは2価と3価があり、さらに水和してみたりα、γ、δなどの相に化けてみたり、身近なのに分かりづらすぎ…。

そういえばセスキ炭酸ナトリウムが最近キッチンや洗濯用に出ていて結構な人気だけれど、これは炭酸ナトリウムと炭酸水素ナトリウムを1:1で混合したもので、弱酸性ではあるけれどタンパク質や脂質を溶かすので衣類の汚れ落としなんかに重宝してるんですが、そろそろパナマ風帽子がひと夏過ぎてちょっとニオイがしてるので洗濯しようと思ってます。

Windowsでシンボリックリンクを試してみる。

きっかけは、1つのファイルを別の名前で起動したら違う動きになるようなスクリプトを書く、でした。  busybox なんかでは、同じ実行形式ファイルの名前を、lsにすればlsと同じ、cpとすればcpと同じ動作をするようにしてますが、Pythonスクリプトでそれと同じように argv...