This article is to show how to start ZWay system running in C++. One of the advantages for using C++ instead of ZWay JavaScript based system is that it gives me more control at system level.
A few days ago I posted a way to access ZWay information via HTTP protocol in Shell Script. But later I found that it doesn't give me the full control I wanted so I continued C++ approach. This post assumes that you installed ZWay on your Raspberry Pi. The instruction of how to install can be found from ZWave.me webpage.
1 2 3 4 5 6 7 8 | // stdafx.h written by Jae Hyuk Kwak #include <stdexcept> // runtime_error #include <iostream> // cerr, cout #include <thread> // this_thread::sleep_for #include <ZWayLib.h> #include <ZDataPublic.h> #include <ZLogging.h> using namespace std; |
1 2 3 4 5 6 7 8 9 | // config.hpp written by Jae Hyuk Kwak namespace Configuration { // check config.xml for the device path ZWCSTR devPath = ZSTR( "/dev/ttyAMA0" ); ZWCSTR configPath = ZSTR( "/opt/z-way-server/config" ); ZWCSTR translationsPath = ZSTR( "/opt/z-way-server/translations" ); ZWCSTR ZDDXPath = ZSTR( "/opt/z-way-server/ZDDX" ); } |
1 2 3 4 5 6 7 8 9 10 11 | // myzway.cpp written by Jae Hyuk Kwak #include "stdafx.h" #include "MyZWay.hpp" #include "config.hpp" using namespace Configuration; using namespace MyZWayNS; int main( int argc, char *argv[] ) { Init myZWay( devPath, configPath, translationsPath, ZDDXPath ); return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # Makefile written by Jae Hyuk Kwak CC=g++-4.7 LD_LIBRARY_PATH=/opt/z-way-server/libs CFLAGS=-Wall -g -std=c++11 -I/opt/z-way-server/libzway-dev/ -L/opt/z-way-server/libs all: myzway myzway: *.hpp myzway.cpp stdafx.h.gch $(CC) $(CFLAGS) -o myzway myzway.cpp -lzway -lxml2 -larchive -lssl -Wl,-rpath=$(LD_LIBRARY_PATH) stdafx.h.gch: stdafx.h $(CC) $(CFLAGS) -c stdafx.h clean: rm stdafx.h.gch myzway |
Note that Makefile has an option, "-Wl,-rpath,$(LD_LIBRARY_PATH)" and LD_LIBRARY_PATH is "/opt/z-way-server/libs". This is to link the runtime library at compile time. Without this option, you will need to change the environment variable, LD_LIBRARY_PATH, before every time you want to launch the program. You can do that by typing in "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/z-way-server/libs". But again, I found it easier to just link it at compile time.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | // MyZWay.hpp written by Jae Hyuk Kwak namespace MyZWayNS { static const uint32_t idleTimeout = 60u; // in seconds static const bool enableDebug = false; void WaitUntilAvailable( ZWay zway ); runtime_error critical( ZWay zway, const char *msg, ZWError r ); class Init { ZWay zway_; public: Init( ZWCSTR devPath, ZWCSTR configPath, ZWCSTR translationsPath, ZWCSTR ZDDXPath ) { memset( &zway_, 0, sizeof( ZWay ) ); // required if ( ZWError r = zway_init( &zway_, devPath, configPath, translationsPath, ZDDXPath, NULL, enableDebug ? Debug : Critical ) ) throw critical( zway_, "zway_init() failed.", r ); if ( ZWError r = zway_start( zway_, NULL ) ) throw critical( zway_, "zway_start() failed.", r ); if ( ZWError r = zway_discover( zway_ ) ) throw critical( zway_, "zway_discover() failed.", r ); WaitUntilAvailable( zway_ ); } ~Init() { if ( ZWError r = zway_stop( zway_ ) ) throw critical( zway_, "zway_stop() failed.", r ); zway_terminate( &zway_ ); } ZWay native() { return zway_; } }; void WaitUntilAvailable( ZWay zway ) { if ( !zway_is_running( zway ) ) throw runtime_error( "zway is not running." ); for ( uint32_t idleCounter = 0; idleCounter < idleTimeout; ++idleCounter ) { if ( zway_is_idle( zway ) ) return; this_thread::sleep_for( chrono::seconds( 1 ) ); } throw runtime_error( "zway is too busy" ); } runtime_error critical( ZWay zway, const char *msg, ZWError r ) { zway_log_error( zway, Critical, msg, r ); return runtime_error( msg ); } } |
- zway_init
- zway_start
- zway_discover
- [do whatever we want]
- zway_stop
- zway_terminate
When you execute the program, it may give you an error like the screenshot above:
Failed to exclusively lock device: Resource temporarily unavailable
zway_start failed: Can not open port (-20)
Probably it is because there is another process already running and using the ZWay device. By default, z-way-server starts at booting time. You can manually stop it as the screenshot shows. To permanently disable the service you can type in "sudo update-rc.d z-way-server disable".
This program doesn't to anything but starting the zway server and shut it down. I will show how to access data and send command later.
Hello,
ReplyDeleteActually i work on the same project and i try your program but when i launch Makefile i have an error
"stdafx.h:6:25: fatal error: ZDataPublic.h: No such file or directory
compilation terminated.".
Is it possible to tell me the version of libzway you use cause i dont find ZDataPublic.h ^^ ?
Thanks in advance.