Wiki
Clone wikibacnet-phpextension / Home
本モジュールはオープンソースとして提供します。
自由に改変・再配布していただいて構いません。
ただし、本モジュール使用により発生した如何なる損害・不利益についても当方責任を負いかねます。
また、本モジュールを使用して発生した如何なる損害・不利益についても当方に損害賠償の請求などを行わないことに同意された方のみ利用いただけるものとし、利用した時点で同意されたものといたします。
※lib64ディレクトリにコンパイル済みのモジュールを登録しています。環境条件があえば、そのまま使用できます。
bacnet-phpextensionについて
このコードはPHPの拡張モジュールです。
BacnetプロトコルをPHPから行えるようにするためのモジュールです。
プロトコルスタックとして、bacnet-stack-0.8.6.zipを使用しています。
対応バージョン
ソフトウェア | バージョン |
---|---|
PHP | 7.2 |
bacnet-stack | 0.8.6 |
CentOS Linux | release 7.7.1908 (Core) |
gcc | 4.8.5 20150623 |
この拡張モジュールはphphizeを使わず、phpのソースコード一式を使って構築しています。
以下コンパイルなどの説明をする際にはその環境をベースに説明します。
phphizeを使った環境でコンパイルする際には読み替えが必要な個所は適宜読み替えてください。
コンパイル方法
bacnet-stackをコンパイルします。
このライブラリ自体についてはダウンロード元のサイトで確認ください。
本拡張モジュールをエクステンションとしてロードする形で使用できるようにするためには bacnet-stackを共有ライブラリとしてコンパイルする必要があります。
しかし、bacnet-stackは静的ライブラリとしてコンパイルする形でのMakefileの提供となっています。
ですので、bacnet-stackを共有ライブラリとしてコンパイルできるようにMakefileを変更してコンパイルを実行します。
bacnet-stackのコンパイル
適当な作業ディレクトリに「bacnet-stack-0.8.6.zip」を展開します
$ mv bacnet-stack-0.8.6.zip /usr/local/src/ $ cs /usr/local/src $ unzip bacnet-stack-0.8.6.zip
bacnet-stack-0.8.6/Makefile に以下の変更を加えます
1.共有ライブラリmekeルールの追加
slibrary: $(MAKE) -s -C lib slib
2.makeクリーンに共有ライブラリのクリーンを追加 clean: のルールに
$(MAKE) -s -C lib sclean
bacnet-stack-0.8.6/lib/Makefile を変更します。
#Makefile to build BACnet Library with GCC # tools - only if you need them. # Most platforms have this already defined # CC = gcc # AR = ar # MAKE = make # SIZE = size # # Assumes rm and cp are available BACNET_PORT_DIR = ../ports/${BACNET_PORT} BACNET_OBJECT = ../demo/object BACNET_HANDLER = ../demo/handler BACNET_CORE = ../src BACNET_INCLUDE = ../include # compiler configuration #STANDARDS = -std=c99 INCLUDE1 = -I$(BACNET_PORT_DIR) -I$(BACNET_OBJECT) -I$(BACNET_HANDLER) INCLUDE2 = -I$(BACNET_INCLUDE) INCLUDES = $(INCLUDE1) $(INCLUDE2) # target TARGET = bacnet LIBRARY = lib$(TARGET).a SLIBRARY = lib$(TARGET).so // ここ追加 CORE_SRC = \ $(BACNET_CORE)/apdu.c \ $(BACNET_CORE)/npdu.c \ $(BACNET_CORE)/bacdcode.c \ $(BACNET_CORE)/bacint.c \ $(BACNET_CORE)/bacreal.c \ $(BACNET_CORE)/bacstr.c \ $(BACNET_CORE)/bacapp.c \ $(BACNET_CORE)/bacprop.c \ $(BACNET_CORE)/bactext.c \ $(BACNET_CORE)/bactimevalue.c \ $(BACNET_CORE)/datetime.c \ $(BACNET_CORE)/indtext.c \ $(BACNET_CORE)/key.c \ $(BACNET_CORE)/keylist.c \ $(BACNET_CORE)/proplist.c \ $(BACNET_CORE)/debug.c \ $(BACNET_CORE)/bigend.c \ $(BACNET_CORE)/arf.c \ $(BACNET_CORE)/awf.c \ $(BACNET_CORE)/cov.c \ $(BACNET_CORE)/dcc.c \ $(BACNET_CORE)/iam.c \ $(BACNET_CORE)/ihave.c \ $(BACNET_CORE)/rd.c \ $(BACNET_CORE)/rp.c \ $(BACNET_CORE)/rpm.c \ $(BACNET_CORE)/timesync.c \ $(BACNET_CORE)/whohas.c \ $(BACNET_CORE)/whois.c \ $(BACNET_CORE)/wp.c \ $(BACNET_CORE)/wpm.c \ $(BACNET_CORE)/abort.c \ $(BACNET_CORE)/reject.c \ $(BACNET_CORE)/bacerror.c \ $(BACNET_CORE)/ptransfer.c \ $(BACNET_CORE)/memcopy.c \ $(BACNET_CORE)/filename.c \ $(BACNET_CORE)/tsm.c \ $(BACNET_CORE)/bacaddr.c \ $(BACNET_CORE)/address.c \ $(BACNET_CORE)/bacdevobjpropref.c \ $(BACNET_CORE)/bacpropstates.c \ $(BACNET_CORE)/alarm_ack.c \ $(BACNET_CORE)/event.c \ $(BACNET_CORE)/getevent.c \ $(BACNET_CORE)/get_alarm_sum.c \ $(BACNET_CORE)/readrange.c \ $(BACNET_CORE)/timestamp.c \ $(BACNET_CORE)/version.c HANDLER_SRC = \ $(BACNET_HANDLER)/dlenv.c \ $(BACNET_HANDLER)/txbuf.c \ $(BACNET_HANDLER)/noserv.c \ $(BACNET_HANDLER)/h_npdu.c \ $(BACNET_HANDLER)/h_whois.c \ $(BACNET_HANDLER)/h_iam.c \ $(BACNET_HANDLER)/h_rp.c \ $(BACNET_HANDLER)/h_rp_a.c \ $(BACNET_HANDLER)/h_rpm.c \ $(BACNET_HANDLER)/h_rpm_a.c \ $(BACNET_HANDLER)/h_rr.c \ $(BACNET_HANDLER)/h_rr_a.c \ $(BACNET_HANDLER)/h_wp.c \ $(BACNET_HANDLER)/h_wpm.c \ $(BACNET_HANDLER)/h_alarm_ack.c \ $(BACNET_HANDLER)/h_arf.c \ $(BACNET_HANDLER)/h_arf_a.c \ $(BACNET_HANDLER)/h_awf.c \ $(BACNET_HANDLER)/h_rd.c \ $(BACNET_HANDLER)/h_dcc.c \ $(BACNET_HANDLER)/h_ts.c \ $(BACNET_HANDLER)/h_whohas.c \ $(BACNET_HANDLER)/h_ihave.c \ $(BACNET_HANDLER)/h_cov.c \ $(BACNET_HANDLER)/h_ccov.c \ $(BACNET_HANDLER)/h_ucov.c \ $(BACNET_HANDLER)/h_getevent.c \ $(BACNET_HANDLER)/h_gas_a.c \ $(BACNET_HANDLER)/h_get_alarm_sum.c \ $(BACNET_HANDLER)/h_pt.c \ $(BACNET_HANDLER)/h_pt_a.c \ $(BACNET_HANDLER)/h_upt.c \ $(BACNET_HANDLER)/s_arfs.c \ $(BACNET_HANDLER)/s_awfs.c \ $(BACNET_HANDLER)/s_dcc.c \ $(BACNET_HANDLER)/s_ihave.c \ $(BACNET_HANDLER)/s_iam.c \ $(BACNET_HANDLER)/s_cov.c \ $(BACNET_HANDLER)/s_ptransfer.c \ $(BACNET_HANDLER)/s_rd.c \ $(BACNET_HANDLER)/s_rp.c \ $(BACNET_HANDLER)/s_rpm.c \ $(BACNET_HANDLER)/s_readrange.c \ $(BACNET_HANDLER)/s_ts.c \ $(BACNET_HANDLER)/s_cevent.c \ $(BACNET_HANDLER)/s_router.c \ $(BACNET_HANDLER)/s_uevent.c \ $(BACNET_HANDLER)/s_whohas.c \ $(BACNET_HANDLER)/s_whois.c \ $(BACNET_HANDLER)/s_wpm.c \ $(BACNET_HANDLER)/s_upt.c \ $(BACNET_HANDLER)/s_wp.c PORT_ARCNET_SRC = \ $(BACNET_PORT_DIR)/arcnet.c PORT_MSTP_SRC = \ $(BACNET_PORT_DIR)/rs485.c \ $(BACNET_PORT_DIR)/dlmstp.c \ $(BACNET_PORT_DIR)/timer.c \ $(BACNET_CORE)/ringbuf.c \ $(BACNET_CORE)/fifo.c \ $(BACNET_CORE)/mstp.c \ $(BACNET_CORE)/mstptext.c \ $(BACNET_CORE)/crc.c \ PORT_ETHERNET_SRC = \ $(BACNET_PORT_DIR)/ethernet.c PORT_BIP_SRC = \ $(BACNET_PORT_DIR)/bip-init.c \ $(BACNET_CORE)/bvlc.c \ $(BACNET_CORE)/bip.c PORT_BIP6_SRC = \ $(BACNET_HANDLER)/h_bbmd6.c \ $(BACNET_PORT_DIR)/bip6.c \ $(BACNET_CORE)/vmac.c \ $(BACNET_CORE)/bvlc6.c PORT_ALL_SRC = \ $(PORT_ARCNET_SRC) \ $(PORT_MSTP_SRC) \ $(PORT_ETHERNET_SRC) \ $(PORT_BIP_SRC) \ $(PORT_BIP6_SRC) ifeq (${BACDL_DEFINE},-DBACDL_BIP=1) PORT_SRC = ${PORT_BIP_SRC} endif ifeq (${BACDL_DEFINE},-DBACDL_BIP6=1) PORT_SRC = ${PORT_BIP6_SRC} endif ifeq (${BACDL_DEFINE},-DBACDL_MSTP=1) PORT_SRC = ${PORT_MSTP_SRC} endif ifeq (${BACDL_DEFINE},-DBACDL_ARCNET=1) PORT_SRC = ${PORT_ARCNET_SRC} endif ifeq (${BACDL_DEFINE},-DBACDL_ETHERNET=1) PORT_SRC = ${PORT_ETHERNET_SRC} endif ifdef BACDL_ALL PORT_SRC = ${PORT_ALL_SRC} endif // ここから DEVICE_SRC = \ ${BACNET_OBJECT}/device.c \ ${BACNET_OBJECT}/ai.c \ ${BACNET_OBJECT}/ao.c \ ${BACNET_OBJECT}/av.c \ ${BACNET_OBJECT}/bi.c \ ${BACNET_OBJECT}/bo.c \ ${BACNET_OBJECT}/bv.c \ ${BACNET_OBJECT}/nc.c \ ${BACNET_OBJECT}/lsp.c \ ${BACNET_OBJECT}/lc.c \ ${BACNET_OBJECT}/ms-input.c \ ${BACNET_OBJECT}/mso.c \ ${BACNET_OBJECT}/msv.c \ ${BACNET_OBJECT}/trendlog.c \ ${BACNET_OBJECT}/bacfile.c \ ${BACNET_OBJECT}/osv.c \ ${BACNET_OBJECT}/piv.c \ ${BACNET_OBJECT}/schedule.c // ここまで追加 SRCS = ${CORE_SRC} ${PORT_SRC} ${HANDLER_SRC} SRCS2 = ${CORE_SRC} ${PORT_SRC} ${HANDLER_SRC} ${DEVICE_SRC} // ここ追加 OBJS = ${SRCS:.c=.o} SOBJS = ${SRCS2:.c=.o} // ここ追加 # use local includes, but other values from calling Makefile CFLAGS = $(WARNINGS) $(DEBUGGING) $(OPTIMIZATION) $(STANDARDS) $(INCLUDES) $(DEFINES) all: $(LIBRARY) lib: $(LIBRARY) slib: $(SLIBRARY) // ここ追加 $(LIBRARY): $(OBJS) Makefile $(AR) rcs $@ $(OBJS) .c.o: ${CC} -c ${CFLAGS} $*.c -o $@ depend: rm -f .depend ${CC} -MM ${CFLAGS} *.c >> .depend clean: rm -rf core $(OBJS) $(LIBRARY) include: .depend // ここから $(SLIBRARY): $(SOBJS) Makefile ${CC} -shared -fPIC -o libbacnet.so $(SOBJS) $(SOBJS): ${CC} -c ${CFLAGS} -fPIC $*.c -o $@ sclean: rm -rf core $(SOBJS) $(SLIBRARY) // ここまで追加
コンパイルを開始します。
$ make clean $ make slibrary
を実行すると、/lib ディレクトリにlibbacnet.so
が生成されます。
※「 -fPIC を付けて再コンパイルしてください」というようなエラーが発生する場合
make clean が正しく行われていない可能性があります。
※make cleanをすると、コンパイル済みのファイルがすべて削除されます。
本拡張モジュールを使うにあたって、作成されたlibbacnet.so
は/usr/lib64/に
コピー、移動、あるいはシンボリックリンクを貼ってください。
追加したライブラリを有効にするために
$ sudo ldconfig
本拡張モジュールのコンパイル
phpのソースを展開したディレクトリを/usr/local/src/php-src
とした場合、
/usr/local/src/php-src/ext/bacnet/
ディレクトリとして本コードをクローンします。
そのうえで、/usr/local/src/php-src
にて
$ ./buildconf
$ ./configure --with-bacnet=shared
$ ./make
を実行します。コンパイルに成功すれば、modules/bacnet.so
が生成されています。
テストは
$ ./sapi/cli/php -d extension=./modules/bacnet.so -f ./ext/bacnet/test_bacnet.php
使い方
以下一例です。
#!php <?php class TestBACNet { protected $bacnetInstance; public $deviceInstance = 1245; // public $deviceInstance = 112233; public $objectType; public $objectInstance; public $property; public function __construct($port = null, $bbmdPort = null, $bbmdAddress = null) { $this->bacnetInstance = new Bacnet($port, $bbmdPort, $bbmdAddress); $this->bacnetInstance->initialize(); // $this->bacnetInstance = new Bacnet(); // $this->bacnetInstance->initialize($port, $bbmdPort, $bbmdAddress); } public function initialize($port = null, $bbmdPort = null, $bbmdAddress = null) { $this->bacnetInstance->initialize($port, $bbmdPort, $bbmdAddress); } public function setDeviceInstance($di) { $this->deviceInstance = $di; } public function getBacnetInstance() { if(!$this->bacnetInstance) { $this->bacnetInstance = new Bacnet(); } return $this->bacnetInstance; } public function readPropetyHandler($arg) { print("--read propety--\n"); var_dump($arg); } public function readRangeHandler($arg) { print("--read range--\n"); var_dump($arg); } public function whois() { $res = $this->bacnetInstance->whois(); var_dump($res); } public function readPropety() { $di = $this->deviceInstance; $ot = 8; $oi = $this->deviceInstance; $prop = 75; // $prop = 76; $ot = 1; $oi = 0; $prop = 85; $this->bacnetInstance->readPropertyAckHandler([$this, "readPropetyHandler"]); $res = $this->bacnetInstance->readprop($di, $ot, $oi, $prop); if(!$res) { var_dump($this->bacnetInstance->getLastErrorMsg()); } } public function readRange() { $di = $this->deviceInstance; $ot = 20; $oi = 2; $prop = 131; $dt = 4; $this->bacnetInstance->readRangeAckHandler([$this, "readRangeHandler"]); $res = $this->bacnetInstance->readrange($di, $ot, $oi, $prop, $dt); if(!$res) { var_dump($this->bacnetInstance->getLastErrorMsg()); } } } //$obj = new TestBACNet(); $obj1 = new TestBACNet(47809, 47808, '192.168.8.220'); $obj2 = new TestBACNet(); $obj2->setDeviceInstance(112233); // whois //$obj->whois(); // readprop $obj1->readPropety(); $obj2->readPropety(); // readrange $obj1->readRange(); $obj2->readRange();
本モジュールを有効にすることで、Bacnetクラスが使えるようになります。
このクラスが、whois、readprop、readrangeメソッドを持っており、適切な引数で呼び出すことでbacnetプロトコルを実行できます。
readprop、readrangeメソッドは非同期処理になるので、コールバックメソッドを登録して結果を取得します。
また、プロパティ名、プロパティ値、オブジェクトタイプ名、オブジェクト対応値はそれぞれ getPropName(10)、getPropIdFromName('apdu-segment-timeout')、getObjectName(14)、getObjectTypeFromName('multi-state-output')メソッドで 対応したものを取得することができます。
注意事項
※PHP拡張機能は + 1.ZTSかNTSかどちらのmaintainerか + 2.デバックモードが有効かどうか + 3.PHPのバージョン が一致している必要があります。
CentOSでは、NTZ、no-debugでコンパイルされたPHPがインストールされているので、上述のコンパイルオプションとなりますが、 環境に応じて変更する必要があります。
ZTSでコンパイルするには、
--enable-maintainer-zts
デバッグモードでコンパイルするには
--enable-debug
を./configure 時にオプションに追加する必要があります。
参考URL
Updated