Commit fd5fa01a416b8e5489fbc68fdd17212c14393072
Committed by
Moritz Wirger
1 parent
3323e501
Add more documentation pages with more detailed instructions, add second example program.
Showing
9 changed files
with
404 additions
and
9 deletions
doc/markdown/Build.md
0 → 100644
| 1 | +# Build and install {#build} | |
| 2 | + | |
| 3 | +# Basic installation {#basic-install} | |
| 4 | + | |
| 5 | +## Clone from github {#clone} | |
| 6 | +To get the newest version of the hueplusplus library, clone it directly from [github](https://github.com/enwi/hueplusplus). | |
| 7 | +The master branch contains the latest tested and stable version, while the development branch is more unstable. | |
| 8 | +```{.sh} | |
| 9 | +~ $ git clone https://github.com/enwi/hueplusplus.git | |
| 10 | +``` | |
| 11 | +This creates a folder hueplusplus with the library sources. | |
| 12 | + | |
| 13 | +When you want to update the library for a new version, use pull with rebase. | |
| 14 | +```{.sh} | |
| 15 | +~/hueplusplus $ git pull --rebase | |
| 16 | +``` | |
| 17 | + | |
| 18 | +## Build with CMake {#build-cmake} | |
| 19 | +To build the library, you need to use [CMake](https://cmake.org) version 3.8 or higher. | |
| 20 | +It is easiest to create a separate build directory where the build files are stored. | |
| 21 | +```{.sh} | |
| 22 | +~/hueplusplus $ mkdir build | |
| 23 | +~/hueplusplus $ cd build | |
| 24 | +~/hueplusplus/build $ cmake .. | |
| 25 | +~/hueplusplus/build $ make | |
| 26 | +``` | |
| 27 | + | |
| 28 | +To install or uninstall the library use the make targets. | |
| 29 | +```{.sh} | |
| 30 | +~/hueplusplus/build $ make install | |
| 31 | +~/hueplusplus/build $ make uninstall | |
| 32 | +``` | |
| 33 | + | |
| 34 | +## Use in a CMake project {#import-cmake} | |
| 35 | +If you have a project that already uses CMake you probably want to add the hueplusplus library directly in your cmake file. | |
| 36 | +For that the best way is to use find_package(). | |
| 37 | +```{.cmake} | |
| 38 | +find_package(hueplusplus REQUIRED) | |
| 39 | +``` | |
| 40 | +But this will only work if the hueplusplus library is already installed. | |
| 41 | +Instead, if you have the hueplusplus repository included in your project repository (as a submodule) or know where the folder lives you can do the following: | |
| 42 | +```{.cmake} | |
| 43 | +find_package(hueplusplus QUIET) | |
| 44 | +if(NOT hueplusplus_FOUND) | |
| 45 | + message(STATUS "-- hueplusplus not found, building it") | |
| 46 | + add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/<path to directory>/hueplusplus" "${CMAKE_CURRENT_BINARY_DIR}/hueplusplus") | |
| 47 | +endif() | |
| 48 | +``` | |
| 49 | +This will check if the hueplusplus library was found by find_package() and if not it will use the specified path to the library source and compile it during the build process. | |
| 50 | + | |
| 51 | +The cmake project defines two library targets: `hueplusplusstatic` to link as a static library and `hueplusplusshared` to link as a shared library. | |
| 52 | +```{.cmake} | |
| 53 | +target_link_libraries(<executable> PUBLIC hueplusplusstatic) | |
| 54 | +``` | |
| 55 | + | |
| 56 | +## Use in another project {#import-other} | |
| 57 | +When you are not using CMake, you have to install hueplusplus and change your build configuration to link to the compiled library. | |
| 58 | +The header files in the include directory need to be added to the include path. | |
| 59 | +How you do this depends on the build system. | |
| 60 | + | |
| 61 | +## Building tests {#build-tests} | |
| 62 | +If you additionally want to run the tests use cmake with the option -Dhueplusplus_TESTS=ON. Testing is done with Google gtest and gmock. Note that you wont need to install gtest/gmock yourself, because cmake will automatically download them and include them during the build. | |
| 63 | +The custom target `unittest` compiles and executes all tests. | |
| 64 | +```bash | |
| 65 | +mkdir build | |
| 66 | +cd build | |
| 67 | +cmake .. -Dhueplusplus_TESTS=ON | |
| 68 | +make unittest | |
| 69 | +``` | |
| 70 | + | |
| 71 | +If you also want to execute coverage tests you will need to install gcov and lcov yourself. To run the coverage test use | |
| 72 | +```bash | |
| 73 | +make coveragetest | |
| 74 | +``` | |
| 75 | + | |
| 76 | +## Building examples {#build-examples} | |
| 77 | +There are some small example programs using this library in the examples folder. To build them, | |
| 78 | +set `hueplusplus_SAMPLES=ON`. The target `hueplusplus_examples` builds all examples into build/examples. | |
| 79 | +```{.sh} | |
| 80 | +mkdir build | |
| 81 | +cd build | |
| 82 | +cmake .. -Dhueplusplus_SAMPLES=ON | |
| 83 | +make hueplusplus_examples | |
| 84 | +``` | ... | ... |
doc/markdown/Getting_Started.md
0 → 100644
| 1 | +# Getting started {#getting-started} | |
| 2 | + | |
| 3 | +## Creating the Hue bridge | |
| 4 | +To start searching for a Hue Bridge you will need to choose an IHttpHandler and create one. | |
| 5 | +The options are a [WinHttpHandler](@ref hueplusplus::WinHttpHandler) (for windows) or a [LinHttpHandler](@ref hueplusplus::LinHttpHandler) (for linux or linux-like). | |
| 6 | + | |
| 7 | +Then create a [BridgeFinder](@ref hueplusplus::BridgeFinder) object with the handler. | |
| 8 | +The handler is needed, because it tells the finder which functions to use to communicate with a bridge or your local network. | |
| 9 | +After that you can call [findBridges()](@ref hueplusplus::HueFinder::findBridges), which will return a vector containing the ip and mac address of all found Bridges. | |
| 10 | +```{.cpp} | |
| 11 | +// For windows use std::make_shared<hueplusplus::WinHttpHandler>(); | |
| 12 | +auto handler = std::make_shared<hueplusplus::LinHttpHandler>(); | |
| 13 | +hueplusplus::BridgeFinder finder(handler); | |
| 14 | +std::vector<hueplusplus::BridgeFinder::BridgeIdentification> bridges = finder.findBridges(); | |
| 15 | +if (bridges.empty()) | |
| 16 | +{ | |
| 17 | + std::cerr << "No bridges found\n"; | |
| 18 | + return; | |
| 19 | +} | |
| 20 | +``` | |
| 21 | + | |
| 22 | +## Authenticate Bridges | |
| 23 | +If you have found the Bridge you were looking for, you can then move on with the authentication process. | |
| 24 | +To get a new username from the Bridge (for now) you simply call [getBridge(bridges[\<index\>])](@ref hueplusplus::BridgeFinder::getBridge), | |
| 25 | +where index is your preferred Bridge from the part [Searching for Bridges](#searchingBridges). This requires the user to press the link button. | |
| 26 | +```{.cpp} | |
| 27 | +hueplusplus::Bridge bridge = finder.getBridge(bridges[0]); | |
| 28 | +``` | |
| 29 | +If you on the other hand already have a username you can add your bridge like so | |
| 30 | +```{.cpp} | |
| 31 | +finder.addUsername(bridges[0].mac, "<username>"); | |
| 32 | +hueplusplus::Bridge bridge = finder.getBridge(bridges[0]); | |
| 33 | +``` | |
| 34 | +If you do not want to use the HueFinder or you already know the ip and username of your bridge you have the option to create your own Hue object. | |
| 35 | +Here you will need to provide the ip address, the port number, a username and an HttpHandler | |
| 36 | +```{.cpp} | |
| 37 | +// For windows use std::make_shared<hueplusplus::WinHttpHandler>(); | |
| 38 | +auto handler = std::make_shared<hueplusplus::LinHttpHandler>(); | |
| 39 | +hueplusplus::Bridge bridge("192.168.2.102", 80, "<username>", handler); | |
| 40 | +``` | |
| 41 | + | |
| 42 | +### Controlling lights | |
| 43 | + | |
| 44 | +```{.cpp} | |
| 45 | +hueplusplus::Light light = bridge.getLight(1); | |
| 46 | +light1.On(); | |
| 47 | +light1.Off(); | |
| 48 | +``` | |
| 49 | + | |
| 50 | +### Controlling groups | |
| 51 | + | |
| 52 | +```{.cpp} | |
| 53 | +hueplusplus::Group group = bridge.getGroup(1); | |
| 54 | +group.setOn(true); | |
| 55 | +``` | |
| 56 | + | |
| 57 | +## More information | |
| 58 | +- [Transactions](@ref transactions) | |
| 0 | 59 | \ No newline at end of file | ... | ... |
doc/markdown/Mainpage.md
| ... | ... | @@ -17,7 +17,8 @@ A simple and easy to use library for Philips Hue Lights. |
| 17 | 17 | * Espressif ESP32 SDK & Arduino |
| 18 | 18 | |
| 19 | 19 | ## How to use |
| 20 | -### <a name="searchingBridges"></a>Searching for Bridges | |
| 20 | +- [Getting Started](@ref getting-started) | |
| 21 | +### Searching for Bridges | |
| 21 | 22 | To start searching for a Hue Bridge you will need to choose an IHttpHandler and create one. The options are a [WinHttpHandler](@ref hueplusplus::WinHttpHandler) (for windows) or a [LinHttpHandler](@ref hueplusplus::LinHttpHandler) (for linux or linux-like). |
| 22 | 23 | |
| 23 | 24 | Then create a [BridgeFinder](@ref hueplusplus::BridgeFinder) object with the handler. |
| ... | ... | @@ -94,6 +95,8 @@ light1.hasColorControl(); |
| 94 | 95 | These will either return true(light has specified function) or false(light lacks specified function). |
| 95 | 96 | |
| 96 | 97 | ## Build and install |
| 98 | +- [Build and install guide](@ref build) | |
| 99 | + | |
| 97 | 100 | ### Basic installation |
| 98 | 101 | If you want to build the library you can use cmake (at least version 3.8). First create a build folder and then execute cmake. |
| 99 | 102 | ```bash | ... | ... |
doc/markdown/Sensors.md
0 → 100644
| 1 | +# Sensors {#sensors} | |
| 2 | + | |
| 3 | +## Sensor support | |
| 4 | +The library supports the sensor types listed on the Hue developer documentation. | |
| 5 | +Other sensors can be used with the generic [Sensor](@ref hueplusplus::Sensor) class. | |
| 6 | + | |
| 7 | +### Working with a known sensor | |
| 8 | +In most cases, the type of the sensors is known in advance, such as a switch. | |
| 9 | +The classes in the [sensors](@ref hueplusplus::sensors) namespace provide the documented | |
| 10 | +functionality. The type can be specified when accessing the sensor. When it does not match, | |
| 11 | +an exception is thrown. | |
| 12 | +```{.cpp} | |
| 13 | +hueplusplus::sensors::ZLLSwitch switchSensor = bridge.sensors().getAsType<hueplusplus::sensors::ZLLSwitch>(2); | |
| 14 | +``` | |
| 15 | + | |
| 16 | +You can also get all sensors of a specified type by using [getAllByType<T>()](@ref hueplusplus::SensorList::getAllByType). | |
| 17 | +```{.cpp} | |
| 18 | +std::vector<hueplusplus::sensors::ZLLSwitch> allSwitches = bridge.sensors().getAllByType<hueplusplus::sensors::ZLLSwitch>(); | |
| 19 | +``` | |
| 20 | + | |
| 21 | +### Working with an unknown sensor | |
| 22 | +When the sensor type is not known, use the generic sensor class. In this case, some attributes might not | |
| 23 | +exist, so they have to be checked first. This applies to all attributes that have a `hasXXX` method. | |
| 24 | + | |
| 25 | +```{.cpp} | |
| 26 | +hueplusplus::Sensor genericSensor = bridge.sensors().get(1); | |
| 27 | +if(genericSensor.hasOn()) | |
| 28 | +{ | |
| 29 | + // Now can check whether it is on | |
| 30 | + if(genericSensor.isOn()) | |
| 31 | + { | |
| 32 | + // ... | |
| 33 | + } | |
| 34 | +} | |
| 35 | +``` | |
| 36 | + | |
| 37 | +It is easiest to compare the sensor type to the existing ones (`typeStr` on the specific sensor classes) | |
| 38 | +and then convert the sensor to that type. | |
| 39 | +```{.cpp} | |
| 40 | +hueplusplus::Sensor genericSensor = bridge.sensors().get(1); | |
| 41 | +if(genericSensor.getType() == hueplusplus::sensors::ZLLSwitch::typeStr) | |
| 42 | +{ | |
| 43 | + hueplusplus::sensors::ZLLSwitch switchSensor = genericSensor.asSensorType<hueplusplus::sensors::ZLLSwitch>(); | |
| 44 | + // ... | |
| 45 | +} | |
| 46 | +``` | |
| 47 | + | |
| 48 | +## ZLL sensors vs. CLIP sensors | |
| 49 | +ZLL sensors (defined in `ZLLSensors.h`) are physical device sensors which send their data | |
| 50 | +to the bridge using ZigBee. They are added in the same way as lights are, using [search()](@ref hueplusplus::SearchableResourceList::search). | |
| 51 | + | |
| 52 | +CLIP sensors (in `CLIPSensors.h`) are added using [create()](@ref hueplusplus::CreateableResourceList::create) with [CreateSensor](@ref hueplusplus::CreateSensor) | |
| 53 | +for parameters. In general, which config and state attributes exist is specified when the sensor is created. | |
| 54 | +The values of CLIP sensors can be changed using requests, unlike ZLL sensors. They can also have a URL to query from. | |
| 55 | + | |
| 56 | +## Creating conditions | |
| 57 | +The most important use for sensors is in [Rules](@ref hueplusplus::Rule), to trigger changes. | |
| 58 | +Conditions can be created from the specific sensor types using `makeCondition()`. | |
| 59 | + | |
| 60 | +These functions return a helper class with methods for the [possible operators](@ref hueplusplus::Condition::Operator) valid for the state. | |
| 61 | + | |
| 62 | +For some sensors, which have multiple possible states, there exist multiple variations of makeCondition. | |
| 63 | + | |
| 64 | +```{.cpp} | |
| 65 | +hueplusplus::sensors::ZLLSwitch switchSensor = ...; | |
| 66 | +// ZLLSwitch conditions operate on `buttonEvent`, use makeConditionLastUpdate() | |
| 67 | +// to trigger on the last update time. | |
| 68 | + | |
| 69 | +// Some examples: | |
| 70 | +hueplusplus::Condition upPressed = makeCondition(switchSensor).eq(hueplusplus::sensors::ZLLSwitch::c_UP_INITIAL_PRESS); | |
| 71 | +hueplusplus::Condition buttonChanged = makeCondition(switchSensor).dx(); | |
| 72 | + | |
| 73 | +hueplusplus::time::TimeInterval interval(std::chrono::hours(12), std::chrono::hours(13)); | |
| 74 | +hueplusplus::Condition updatedAtNoon = makeConditionLastUpdate(switchSensor).in(interval); | |
| 75 | +``` | |
| 76 | + | |
| 77 | +For generic sensors, the conditions must be created manually using the [Condition](@ref hueplusplus::Condition::Condition) | |
| 78 | +constructor with a proper address to the sensor state. | |
| 0 | 79 | \ No newline at end of file | ... | ... |
doc/markdown/Transactions.md
0 → 100644
| 1 | +# Transactions {#transactions} | |
| 2 | + | |
| 3 | +## Using a transaction for lights | |
| 4 | +Often, you want to change more than one variable on a light at the same time, | |
| 5 | +for example brightness and color. This is done using transactions ([StateTransaction](@ref hueplusplus::StateTransaction)). | |
| 6 | + | |
| 7 | +```{.cpp} | |
| 8 | +light.transaction().setOn(true).setBrightness(29).setColorHue(3000).setColorSaturation(128).commit(); | |
| 9 | +``` | |
| 10 | +The request is reduced to only the variables that need to be changed based on the current state. | |
| 11 | +For example, if the light is already on, that part of the transaction is ignored. | |
| 12 | + | |
| 13 | +__Important:__ The transaction has an internal reference to the light state. | |
| 14 | +You must not cause a refresh of the state between creating and committing the transaction (e.g. non-const getters/setters), | |
| 15 | +because that invalidates the reference. | |
| 16 | + | |
| 17 | +### Advanced usage | |
| 18 | +Another way to use the transaction is by storing it and building up the calls separately. | |
| 19 | + | |
| 20 | +```{.cpp} | |
| 21 | +hueplusplus::StateTransaction t = light.transaction(); | |
| 22 | +if(shouldTurnOn) | |
| 23 | + t.setOn(true); | |
| 24 | +t.commit(); | |
| 25 | +``` | |
| 26 | + | |
| 27 | +In this case, it is especially important that the light and the state of the light __MUST NOT__ invalidate. That means | |
| 28 | +* the light variable has to live longer than the transaction | |
| 29 | +* especially no non-const method calls on the light while the transaction is open, or committing other transactions | |
| 30 | + | |
| 31 | +In general, this method is easier to screw up and should only be used when really necessary. | |
| 32 | + | |
| 33 | +## Using a transaction for groups | |
| 34 | +The same principles of transactions for lights also apply for groups. The main difference is that | |
| 35 | +for groups, there are no checks of the current state. Even if all lights in the group are already on, | |
| 36 | +the request to turn on all lights on the group is still sent. | |
| 37 | + | |
| 38 | +```{.cpp} | |
| 39 | +group.transaction().setOn(true).setBrightness(64).commit(); | |
| 40 | +``` | |
| 41 | + | |
| 42 | + | |
| 43 | +## Creating Actions | |
| 44 | +In a [Schedule](@ref hueplusplus::Schedule) or [Rule](@ref hueplusplus::Rule), | |
| 45 | +the bridge can set the state of lights and groups. To configure this, a transaction | |
| 46 | +can be saved for later instead of committing it directly. | |
| 47 | +```{.cpp} | |
| 48 | +hueplusplus::Action action = light.transaction().setOn(true).setBrightness(255).toAction(); | |
| 49 | +schedule.setCommand(action); | |
| 50 | +``` | ... | ... |
examples/BridgeSetup.cpp
| ... | ... | @@ -15,15 +15,17 @@ using SystemHttpHandler = hueplusplus::LinHttpHandler; |
| 15 | 15 | |
| 16 | 16 | #endif |
| 17 | 17 | |
| 18 | +namespace hue = hueplusplus; | |
| 19 | + | |
| 18 | 20 | // Configure existing connections here, or leave empty for new connection |
| 19 | 21 | const std::string macAddress = ""; |
| 20 | 22 | const std::string username = ""; |
| 21 | 23 | |
| 22 | -hueplusplus::Bridge connectToBridge() | |
| 24 | +hue::Bridge connectToBridge() | |
| 23 | 25 | { |
| 24 | - hueplusplus::BridgeFinder finder(std::make_shared<SystemHttpHandler>()); | |
| 26 | + hue::BridgeFinder finder(std::make_shared<SystemHttpHandler>()); | |
| 25 | 27 | |
| 26 | - std::vector<hueplusplus::BridgeFinder::BridgeIdentification> bridges = finder.findBridges(); | |
| 28 | + std::vector<hue::BridgeFinder::BridgeIdentification> bridges = finder.findBridges(); | |
| 27 | 29 | |
| 28 | 30 | for (const auto& bridge : bridges) |
| 29 | 31 | { |
| ... | ... | @@ -59,7 +61,7 @@ int main(int argc, char** argv) |
| 59 | 61 | |
| 60 | 62 | try |
| 61 | 63 | { |
| 62 | - hueplusplus::Bridge hue = connectToBridge(); | |
| 64 | + hue::Bridge hue = connectToBridge(); | |
| 63 | 65 | |
| 64 | 66 | std::cout << "Connected to bridge. IP: " << hue.getBridgeIP() << ", username: " << hue.getUsername() << '\n'; |
| 65 | 67 | } | ... | ... |
examples/CMakeLists.txt
| 1 | -add_executable(bridge_setup BridgeSetup.cpp) | |
| 1 | +add_executable(bridge_setup BridgeSetup.cpp ) | |
| 2 | 2 | set_property(TARGET bridge_setup PROPERTY CXX_STANDARD 14) |
| 3 | 3 | set_property(TARGET bridge_setup PROPERTY CXX_EXTENSIONS OFF) |
| 4 | 4 | target_link_libraries(bridge_setup hueplusplusstatic) |
| 5 | + | |
| 6 | +add_executable(lights_off LightsOff.cpp ) | |
| 7 | +set_property(TARGET lights_off PROPERTY CXX_STANDARD 14) | |
| 8 | +set_property(TARGET lights_off PROPERTY CXX_EXTENSIONS OFF) | |
| 9 | +target_link_libraries(lights_off hueplusplusstatic) | |
| 10 | + | |
| 11 | + | |
| 12 | +add_custom_target(hueplusplus_examples) | |
| 13 | +add_dependencies(hueplusplus_examples bridge_setup) | |
| 5 | 14 | \ No newline at end of file | ... | ... |
examples/LightsOff.cpp
0 → 100644
| 1 | + | |
| 2 | +#include <hueplusplus/Bridge.h> | |
| 3 | + | |
| 4 | +#ifdef _MSC_VER | |
| 5 | +#include <hueplusplus/WinHttpHandler.h> | |
| 6 | + | |
| 7 | +using SystemHttpHandler = hueplusplus::WinHttpHandler; | |
| 8 | + | |
| 9 | +#else | |
| 10 | +#include <hueplusplus/LinHttpHandler.h> | |
| 11 | + | |
| 12 | +using SystemHttpHandler = hueplusplus::LinHttpHandler; | |
| 13 | + | |
| 14 | +#endif | |
| 15 | + | |
| 16 | +namespace hue = hueplusplus; | |
| 17 | + | |
| 18 | +// Configure existing connections here, or leave empty for new connection | |
| 19 | +const std::string macAddress = ""; | |
| 20 | +const std::string username = ""; | |
| 21 | + | |
| 22 | +hue::Bridge connectToBridge() | |
| 23 | +{ | |
| 24 | + hue::BridgeFinder finder(std::make_shared<SystemHttpHandler>()); | |
| 25 | + | |
| 26 | + std::vector<hue::BridgeFinder::BridgeIdentification> bridges = finder.findBridges(); | |
| 27 | + | |
| 28 | + for (const auto& bridge : bridges) | |
| 29 | + { | |
| 30 | + std::cout << "Bridge: " << bridge.mac << " at " << bridge.ip << '\n'; | |
| 31 | + } | |
| 32 | + if (bridges.empty()) | |
| 33 | + { | |
| 34 | + std::cout << "Found no bridges\n"; | |
| 35 | + throw std::runtime_error("no bridges found"); | |
| 36 | + } | |
| 37 | + | |
| 38 | + if (macAddress.empty()) | |
| 39 | + { | |
| 40 | + std::cout << "No bridge given, connecting to first one.\n"; | |
| 41 | + return finder.getBridge(bridges.front()); | |
| 42 | + } | |
| 43 | + if (!username.empty()) | |
| 44 | + { | |
| 45 | + finder.addUsername(macAddress, username); | |
| 46 | + } | |
| 47 | + auto it = std::find_if( | |
| 48 | + bridges.begin(), bridges.end(), [&](const auto& identification) { return identification.mac == macAddress; }); | |
| 49 | + if (it == bridges.end()) | |
| 50 | + { | |
| 51 | + std::cout << "Given bridge not found\n"; | |
| 52 | + throw std::runtime_error("bridge not found"); | |
| 53 | + } | |
| 54 | + return finder.getBridge(*it); | |
| 55 | +} | |
| 56 | + | |
| 57 | +void lightsOff(hue::Bridge& hue) | |
| 58 | +{ | |
| 59 | + std::vector<hue::Light> lights = hue.lights().getAll(); | |
| 60 | + | |
| 61 | + // Save current on state of the lights | |
| 62 | + std::map<int, bool> onMap; | |
| 63 | + for (const hue::Light& l : lights) | |
| 64 | + { | |
| 65 | + onMap.emplace(l.getId(), l.isOn()); | |
| 66 | + } | |
| 67 | + | |
| 68 | + // Group 0 contains all lights, turn all off with a transition of 1 second | |
| 69 | + hue.groups().get(0).setOn(false, 10); | |
| 70 | + std::cout << "Turned off all lights\n"; | |
| 71 | + | |
| 72 | + std::this_thread::sleep_for(std::chrono::seconds(20)); | |
| 73 | + | |
| 74 | + // Restore the original state of the lights | |
| 75 | + for (hue::Light& l : lights) | |
| 76 | + { | |
| 77 | + if (onMap[l.getId()]) | |
| 78 | + { | |
| 79 | + // Refresh, because the state change from the group is not updated in the light. | |
| 80 | + // This is not strictly necessary in this case, because the state is updated | |
| 81 | + // automatically every 10 seconds. | |
| 82 | + // However, when the sleep above is shorter, no refresh can cause the on request | |
| 83 | + // to be removed, because the light thinks it is still on. | |
| 84 | + l.refresh(true); | |
| 85 | + l.on(); | |
| 86 | + } | |
| 87 | + } | |
| 88 | + | |
| 89 | + std::cout << "Turned lights back on\n"; | |
| 90 | +} | |
| 91 | + | |
| 92 | +int main(int argc, char** argv) | |
| 93 | +{ | |
| 94 | + | |
| 95 | + try | |
| 96 | + { | |
| 97 | + hue::Bridge hue = connectToBridge(); | |
| 98 | + | |
| 99 | + std::cout << "Connected to bridge. IP: " << hue.getBridgeIP() << ", username: " << hue.getUsername() << '\n'; | |
| 100 | + | |
| 101 | + lightsOff(hue); | |
| 102 | + } | |
| 103 | + catch (...) | |
| 104 | + { | |
| 105 | + } | |
| 106 | + | |
| 107 | + std::cout << "Press enter to exit\n"; | |
| 108 | + std::cin.get(); | |
| 109 | + | |
| 110 | + return 0; | |
| 111 | +} | |
| 0 | 112 | \ No newline at end of file | ... | ... |
test/CMakeLists.txt
| ... | ... | @@ -63,9 +63,9 @@ set(HuePlusPlus_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/include") |
| 63 | 63 | |
| 64 | 64 | # test executable |
| 65 | 65 | add_executable(test_HuePlusPlus ${TEST_SOURCES}) |
| 66 | -if(DO_CLANG_TIDY) | |
| 67 | - set_target_properties(test_HuePlusPlus PROPERTIES CXX_CLANG_TIDY ${DO_CLANG_TIDY}) | |
| 68 | -endif() | |
| 66 | +#if(DO_CLANG_TIDY) | |
| 67 | +# set_target_properties(test_HuePlusPlus PROPERTIES CXX_CLANG_TIDY ${DO_CLANG_TIDY}) | |
| 68 | +#endif() | |
| 69 | 69 | target_compile_features(test_HuePlusPlus PUBLIC cxx_std_14) |
| 70 | 70 | set_property(TARGET test_HuePlusPlus PROPERTY CXX_EXTENSIONS OFF) |
| 71 | 71 | ... | ... |