廉価版の家庭用エアコンに、JEM-A HA端子が付いているのを発見しました。仕様を調べて、ESP32に接続し、MQTTとHomebridge経由でHomeKitから使えるようにしました。
参考記事のご紹介
Homebridgeについては以下もご覧ください。
MQTTブローカについてはこちらもご覧ください。
ESP32をMQTT, Homebridgeと連携させる方法はこちらをご覧ください。
謎の多いJEM-A端子
日本電機工業会(JEMA)という業界団体が、標準規格を作っています。その業界規格の一つに、家電製品の自動化のために作られたJEMA標準HA端子-Aという端子があります。HAとは多分ホーム・オートメーションのことですね。この名前のほか、JEM-A端子、JEM-A HA端子、JEMA端子、JEM端子-A、JEM1427端子などと呼ばれているようです。以下ではJEM-A端子と書くことにします。JEM-A端子は、エアコン、給湯機、暖房器具、床暖房、電動で開閉する装置、電気錠、インターフォン(電気錠との連携)、電気温水器、照明器具などのon/off制御と、そのon/off状態のモニタを行う端子です。できることは2値の制御とモニターだけで、温度設定とか明るさ設定などの機能は実現できません。
JEM-A端子は、日本の家電メーカの色々な製品に付いていて、スマートホームDIYに使えそうな面白い規格なのですが、あまり情報がありません。こちらのページくらいが一番詳しいかもしれないです。それによると、端子にはC1, C2, M1, M2の4本のピンがあり、2本が制御、2本がモニタで、それぞれに電圧がかかるかどうかでon/offを表してます。これを制御するためには、フォトカプラなどで絶縁してインタフェースするのが良いようです。
( https://mtrx.jp/info/jema.html から引用 )
C1, C2を250ms程度短絡すると、on/offが反転し、その結果、M1, M2に電圧が出たり消えたりするようです。なので、C1, C2に押しボタンスイッチを接続し、M1, M2にモニタランプ(LED)を接続すれば、ボタンを押すごとにon/offが反転してLEDが点灯・消灯するスイッチボックスが簡単に作れそうです。
ただ、これ以上の細かい規格は分かりません。電圧・電流・タイミングの定格値・許容値も謎です。謎な根本理由が、JEMAが技術情報PDFを1,210円で販売していることだと思います。価格は大したことはないのですが、購入した情報を無許可で「出版」してはいけないことになっています。なので、正規の規格書により技術情報を知った人は、ネットに情報公開できません。色々な家電に付いていて、便利な機能なのに勿体無いです。
もう少し探したところ、こちらにJEM-A端子とフォトカプラでインタフェースする製品の仕様書が見つかりました。JEM-A端子の規格についてあからさまには書かれてませんが、製品仕様からある程度の推測ができます。
https://www2.panasonic.biz/ideacontout/2012/11/14/2012111400020152.PDF
(panasonic.bizから引用)
これによると、C1, C2側の耐電圧は30V, 許容電流5mAで、M1, M2側の許容電流は20mAだそうです。M1, M2を2mAで動作させる場合1.6V以下にするようにと書いてあります。回路図も書いてあるので、これを参考に自作すると良いと思いました。フォトカプラに100Ωくらいの抵抗を直列に入れて保護しておけば良いようです。
エアコンのJEM-A端子を発見
JEM-A端子は、意外とあちこちに付いているようです。例えば手近にあるPanasonicのエアコンにもついてました。10年くらい前の、ごく普通の安価な標準モデル家庭用エアコンです。PanasonicのEchonet Light対応機器一覧にも掲載は無く、WiFiも搭載されてません。JEM-A HA端子に関しても、本体にもマニュアルにもどこにも書いてありません。でもなぜか、Panasonicの製品仕様書のページに、JEM-A端子に関する表記がありました。
そこで、エアコンを分解してJEM-A端子を探すことにしました。室内機の右側部分に電子回路がありそうで、薄い鉄板でシールドされてます。下の写真の右端の銀色の部分です。シールドは、噛み合わせの部分にギターピックを挟んで浮かせれば簡単に外れました。
すると、中の基板の手間側に、白いJEM-A端子が見つかりました!下の写真の右下にある4ピンの端子です。上の写真では赤丸のあたりの場所です。
端子の形状もJEM-A端子のものですし、HAとシルク印刷されているので間違いありません。
取説にも掲載が無くて、ここに接続できるオプション製品も無いのに、なぜJEM-A端子があるのか謎です。業界団体とのお付き合いの関係で、仕方なく付けているのかもしれません。現場に「なんでこれ必要なのですか?」のような声があったかもしれません。でもDIYする立場としては、とても嬉しいです。無駄と思っても装備せざるを得なかった端子ならば、活かして差し上げたいと思います。
端子ケーブルを作る
接続するためにはコネクタ付きケーブルが必要です。JEM-Aのケーブルは、モノタロウなどで300円くらいで販売されてますが、送料もかかるし、部品から作った方が安いので、自作することにしました。JEM-A端子の形状はどれも同じです。おそらくは規格で決められているのだと思います。この端子に収まるコネクタは、秋月電子で20個100円で販売されている製品です。自作するには100本で200円のピンも必要です。ピンに配線を接続するためには圧着工具があると良いです。でも半田付けでもokです。こんな感じで完成しました。
圧着工具は無しでもなんとかなりますが、コネクタを外す工具は、絶対に持っていた方が良いです。ペンチやマイナスドライバーで外そうとすると苦労しますし、コネクタやケーブルを損傷させる可能性があります。今回初めてコネクタ抜き工具を使いましたが、とても楽でした。
電気特性を調査する
JEM-A端子の、それぞれのピンの電圧を開放状態で測りました。また1kΩの抵抗を取り付けて負荷かけた時の電圧も測定しました。
C1-C2の電圧は、開放時に5.04V、1kΩの抵抗を取り付けた場合に0.45Vでした。ちなみに1kΩを取り付けたら、エアコンが起動しました。一方で、M1-M2のHIGH電圧は、開放時に4.5V、1kΩの抵抗を取り付けた場合に2.3Vでした。M1-M2のLOW電圧は0.2Vでした。これから内部抵抗を計算しました。どうやら内部の回路は5Vで稼働するTTL回路のようです。内部回路の想像図は以下です。
ネットの情報を見ると、端子に現れる電圧が、12Vや15Vの場合もあるらしいですが、扱いやすい5V電圧で良かったです。この回路図を見ると、C1-C2は安心して短絡できそうです。また、M1-M2も十分な保護抵抗が入っている様子なので、LEDを直結しても大丈夫のようです。実際にLEDを接続し、C1-C2を短絡したら、エアコンがon/offし、LEDが控え目に点灯・消灯しました。
エアコンが稼働するとM1の電圧がHIGHになり、停止するとLOWになります。
インタフェース回路を作る
先のPanasonicの仕様書を参考に、回路を考えました。JEM-A端子は、1, 2, 3, 4番がそれぞれ、C1, C2, M1, M2です。Cが制御用、Mがモニター用で、C1, M1が高電圧側、C2, M2がグラウンド側です。回路図のJEM-A端子側に入っっている100Ω抵抗は、気休めです。内部抵抗を調べたところでは、この抵抗は無しでも大丈夫なはずですが、Panasonicの仕様書にも入っていたので取り入れました。GPIO12は内部でプルアップさせるので、直結です。GPIO13に付けた220Ωの抵抗は、フォトカプラに定格の10mAを流すために入れました。
これをユニバーサル基板で半田付けして作ろうと思ってますが、とりあえずはブレッドボードに作って動作確認します。ブレッドボードも段ボールの上にテープで貼り付けた(仮)な状態です。写真のブレッドボード左上にあるコネクタに、JEM-A端子からのケーブルが挿さってます。このコネクタはブレッドボードにも挿さる仕様なので便利でした。
ESP32をプログラムする
MQTTブローカと通信して、メッセージに従ってJEM-A端子のC1ピンをon/offするプログラムを、ESP32に書きました。これと並行して、JEM-A端子のM1ピンをモニターし、その状況をMQTTブローカに報告します。基本の動作は、
- MQTTブローカーから、mqttthing/fan/setOnトピックにtrueかfalseが来たら、JEM-AのC1, C2端子を250ms間短絡する。(その結果エアコンがon/offします)
- また、JEM-AのM1, M2端子の電圧が変化したら、MQTTのmqttthing/fan/getOnトピックにtrueかfalseを流す。(その結果HomeKitのon/off表示が更新されます)
- さらに10分に1回、C1, C2端子の様子をmqttthing/fan/getOnトピックに流す。(HomeKit表示が実態を反映するための念押しです)
- 必要に応じて、mqttthing/fan/debugトピックに、デバッグ用のメッセージを流す。
という内容です。プログラムは以下です。C1, C2端子のフォトカプラはGPIO 13番に、M1, M2端子はGPIO 12番に接続してあります。MQTTブローカとの通信には、EspMQTTClientライブラリを使ってます。
//ESP32 fan with EspMQTTClient library.
//This will simply on/off an air-conditioner through its JEM-A HA port.
// Sep. 8, 2022. (first version)
#include "EspMQTTClient.h"
EspMQTTClient *client;
//input & output pins and values
#define JEMAOUT 13 //GPIO for photo relay to JEM-A control line.
#define JEMA_ON 1 //value for pulse on
#define JEMA_OFF 0 //value for pulse off
#define JEMAIN 12 //GPIO for photo relay driven by JEM-A monitor line. Pull-up.
#define JEMA_false 1 //value when the fan is off (false)
#define JEMA_true 0 //value when the fan is on (true)
int JEMA_last; //previous value read from JEMAIN.
//WiFi
const char SSID[] = "XXXXXXXX"; //WiFi SSID
const char PASS[] = "xxxxxxxx"; //WiFi password
char CLIENTID[] = "ESP32_xx:xx:xx:xx:xx:xx"; //MAC address is set in setup()
//for example, this will be set to "ESP32_12:34:56:78:9A:BC"
const char MQTTADD[] = "192.168.xxx.xxx"; //Broker IP address
const short MQTTPORT = 1883; //Broker port
const char MQTTUSER[] = "xxxxx";//Can be omitted if not needed
const char MQTTPASS[] = "XXXXX";//Can be omitted if not needed
const char SUBTOPIC[] = "mqttthing/fan/setOn"; //mqtt topic to subscribe
const char PUBTOPIC[] = "mqttthing/fan/getOn"; //mqtt topic to publish
const char PUBDEBUG[] = "mqttthing/fan/debug"; //for debug message
void setup() {
//Digital I/O
pinMode(JEMAOUT, OUTPUT);//for C1-C2 JEM-A pins
pinMode(JEMAIN, INPUT_PULLUP);//for M1-M2 JEM-A pins
JEMA_last=digitalRead(JEMAIN);
//Serial
Serial.begin(115200);
while (!Serial);
Serial.println("ESP32 fan has started.");
//MQTT
String wifiMACString = WiFi.macAddress(); //WiFi MAC address
wifiMACString.toCharArray(&CLIENTID[6], 18, 0); //"ESP32_xx:xx:xx:xx:xx:xx"
Serial.print("SSID: ");Serial.println(SSID);
Serial.print("MQTT broker address: ");Serial.println(MQTTADD);
Serial.print("MQTT clientID: ");Serial.println(CLIENTID);
client = new EspMQTTClient(SSID,PASS,MQTTADD,MQTTUSER,MQTTPASS,CLIENTID,MQTTPORT);
}
void onMessageReceived(const String& msg) { // topic = mqttthing/fan/setOn
if(msg.compareTo("true")==0) { //requeted to set true (ON)
client->publish(PUBDEBUG, "received ture on setOn-topic.");
if(digitalRead(JEMAIN) == JEMA_true) return; //already ON. do nothing.
}
else if(msg.compareTo("false")==0) { //requested to set false (OFF)
client->publish(PUBDEBUG, "received false on setOn-topic.");
if(digitalRead(JEMAIN) == JEMA_false) return; //already OFF. do nothing.
}
//now send a pluse to toggle the fan ON or OFF
client->publish(PUBDEBUG, "sending a pluse to JEM-A.");
digitalWrite(JEMAOUT, JEMA_ON); //activate JEM-A C1C2 for 0.25 sec
delay(250);
digitalWrite(JEMAOUT, JEMA_OFF);
}
int counter; //counter for loops
void onConnectionEstablished() {
Serial.println("WiFi/MQTT onnection established.");
client->subscribe(SUBTOPIC, onMessageReceived); //set callback function
client->publish(PUBDEBUG, "ESP32 fan is ready.");
counter=999999; //to trigger a publish at the next loop
}
void loop() {
client->loop();
int newvalue = digitalRead(JEMAIN);//get current JEMA value
delay(10); //10 ms delay
if(newvalue == JEMA_last) {
if(++counter < 60000) {//check if less than 10 min
return; //no change and no count-up, do nothing
}
}
//JEMA monitor status has chenged or counter is up
if(newvalue == JEMA_true){
client->publish(PUBTOPIC,"true");
}
else{ // if new value == JEMA_false
client->publish(PUBTOPIC,"false");
}
JEMA_last = newvalue;
counter=0;
}
Homebridgeを設定する
Homebridgeにはmqttthingプラグインを入れました。そしてMQTTメッセージに応じて状態が変化するfanアクセサリを作ります。mqttthingの設定は、Homebridge webページのGUIから可能です。その結果、/var/lib/homebridge/config.jsonの設定部分は以下になりました。名前はエアコンにしました。
{
"type": "fan",
"name": "エアコン",
"url": "mqtt://192.168.xxx.xxx:1883",
"username": "xxxxxxxx",
"password": "XXXXXXXX",
"topics": {
"getOn": "mqttthing/fan/getOn",
"setOn": "mqttthing/fan/setOn"
},
"accessory": "mqttthing"
}
HomeKitから操作する
この結果、iPhoneやMacのホーム.appアプリに、「エアコン」という名前のfanアクセサリボタンが現れました。
クリックするとon/offします。頻繁にon/offするとエアコンに負担がかかるので、動作確認が難しいです。mosquitto_subコマンドで、
mosquitto_sub -h 192.168.xxx.xxx -u xxxxxx -P XXXXXX -t mqttthing/fan/# -v
などとしておけば、以下のようにメッセージが確認できます。
mqttthing/fan/debug ESP32 fan is ready. mqttthing/fan/getOn true mqttthing/fan/setOn falsemqttthing/fan/debug received false on setOn-topic. mqttthing/fan/debug sending a pluse to JEM-A.
これはエアコンがoffの状態でESP32を起動させ、iPhoneからonにしたときの流れです。これでアイコンもオンになります。
onにするとアイコンのファンの羽がゆっくり速度を上げて回転開始し、offすると回転が遅くなり止まります。
まとめ
古めのエアコンにJEM-A端子を見つけたので、HomeKitから使えるようにDIYしました。JEM-A端子ではon/offしかできませんので、温度設定の変更には元々のエアコンのリモコンが必要です。でもシンプルに確実に動作しますし、大体の場面ではこれで十分かと思います。
コメント
こちらのブログ、大変興味深く拝見させていただきました。
1つ質問なのですが、こちらの記事の、ESP32の電源はどのようにして取られていますでしょうか。ACアダプタとUSBケーブル経由でしょうか。それとも、エアコンのどこかから5V直流を取られましたでしょうか。
ACアダプタとUSBケーブルを用いるのが簡単ですが、ケーブルが目立つでしょう。エアコン内部で完結させるほうがスマートですが、エアコンの回路に手を入れて電源を取るのは容易ではなさそうです。
いかがなされましたでしょうか。ご教示いただけますと幸いです。
USB ACアダプタを使ってます。エアコンの中から電源取れたら配線がスッキリしますね。
早速のお返事ありがとうございます。エアコン内で完結されると外に余計なものが出ませんので楽なのですが、なかなか難しいです。ひとまずUSB ACアダプタで電源をとる方向で私もやってみようと思います。ありがとうございました。
私は素人ですが、いつもこちらのブログを拝見しており、とても興味深く読ませていただいております。
Raspberry PiでHomebridgeを運用しております。
Panasonicのjem-aおよび電気錠対応ドアホンも使用しております。
家の鍵は電気錠ではなくSwitchbotのスマートロックです。
ラズパイのGPIO端子を活かして、SwitchbotのAPIで取得した鍵の状態をHIGH or LOWでjem-a端子のような挙動を出力し、PanasonicのVL-JY1を使用して、ドアホンに接続したいと考えています。
ラズパイとフォトカプラ?を使用してそのような出力をすることはできますでしょうか?
大学の研究で使用したく、ご教授いただけますと幸いです。
Switchbot APIで錠前の状態や、解錠、施錠ができているのでしたら、ラズパイのGPIOを使ってJEM-Aにインタフェースすることは簡単だと思います。