File: UsernameConfig.cpp

package info (click to toggle)
hueplusplus 1.2.0%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,372 kB
  • sloc: cpp: 14,028; ansic: 70; makefile: 12
file content (149 lines) | stat: -rw-r--r-- 4,402 bytes parent folder | download
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/**
    \file UsernameConfig.cpp
    Copyright Notice\n
    Copyright (C) 2021  Jan Rogall		- developer\n

    This file is part of hueplusplus.

    hueplusplus is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    hueplusplus is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with hueplusplus.  If not, see <http://www.gnu.org/licenses/>.

    \example{lineno} UsernameConfig.cpp
    This example reads the username and mac address from a config file.
**/

#include <algorithm>
#include <fstream>
#include <iomanip>
#include <iostream>

#include <hueplusplus/Bridge.h>

#ifdef _MSC_VER
#include <hueplusplus/WinHttpHandler.h>

using SystemHttpHandler = hueplusplus::WinHttpHandler;

#else
#include <hueplusplus/LinHttpHandler.h>

using SystemHttpHandler = hueplusplus::LinHttpHandler;

#endif

namespace hue = hueplusplus;

// Reads a json config file.
// filename: Path to the config file
// returns parsed json or an empty object if not successful.
nlohmann::json readConfigFile(const std::string& filename)
{
    std::ifstream stream(filename);
    try
    {
        nlohmann::json result = nlohmann::json::object();
        if (stream)
        {
            stream >> result;
        }
        return result;
    }
    catch (const nlohmann::json::exception&)
    {
        // Ignore parse errors
        return nlohmann::json::object();
    }
}

// Saves a json file.
// filename: Path to the config file
// config: Json value to save
void saveConfigFile(const std::string& filename, const nlohmann::json& config)
{
    std::ofstream stream(filename);
    stream << std::setw(4) << config;
}

// Connects to a bridge and returns it
// username: Already existing username, can be left empty.
// macAddress: MAC address of the bridge, can be left empty.
// throws std::runtime_error when the bridge was not found.
// returns a connected bridge.
hue::Bridge connectToBridge(const std::string& username, const std::string& macAddress)
{
    hue::BridgeFinder finder(std::make_shared<SystemHttpHandler>());

    std::vector<hue::BridgeFinder::BridgeIdentification> bridges = finder.findBridges();

    for (const auto& bridge : bridges)
    {
        std::cout << "Bridge: " << bridge.mac << " at " << bridge.ip << '\n';
    }
    if (bridges.empty())
    {
        std::cout << "Found no bridges\n";
        throw std::runtime_error("no bridges found");
    }

    if (macAddress.empty())
    {
        std::cout << "No bridge given, connecting to first one.\n";
        return finder.getBridge(bridges.front());
    }
    if (!username.empty())
    {
        finder.addUsername(macAddress, username);
    }
    auto it = std::find_if(
        bridges.begin(), bridges.end(), [&](const auto& identification) { return identification.mac == macAddress; });
    if (it == bridges.end())
    {
        std::cout << "Given bridge not found\n";
        throw std::runtime_error("bridge not found");
    }
    return finder.getBridge(*it);
}

// Connects to a bridge. The steps are:
// - read "config.json" for an existing config
// - connect to the bridge
// - save the username to the config file for the next run
// 
// Also prints out the IP and username.
int main(int argc, char** argv)
{

    const std::string filename = "config.json";
    try
    {

        nlohmann::json config = readConfigFile(filename);
        const std::string username = config.value("username", "");
        const std::string macAddress = config.value("mac", "");
        hue::Bridge hue = connectToBridge(username, macAddress);

        // Store updated information into file
        config["username"] = hue.getUsername();
        config["mac"] = hue.config().getMACAddress();
        saveConfigFile(filename, config);

        std::cout << "Connected to bridge. IP: " << hue.getBridgeIP() << ", username: " << hue.getUsername() << '\n';
    }
    catch (...)
    { }

    std::cout << "Press enter to exit\n";
    std::cin.get();

    return 0;
}