Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX: [hue] proper save state #1014

Merged
merged 3 commits into from
Nov 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Change links from http to https (#1067)

### Fixed
- Properly save Hue light state between sessions (#1014)
- AVAHI included in Webserver (#996)
- Also allow an 8-LED configuration when using Karatelight (#1037)
- Fix #1007 - LED's retain last state after clearing a source (#1008)
Expand All @@ -42,6 +43,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fix typos (#1051)
- Fix Python reset thread state


### Removed
- Replace Multi-Lightpack by multi-instance Lightpack configuration (#1049)

Expand Down
110 changes: 65 additions & 45 deletions libsrc/leddevice/dev_net/LedDevicePhilipsHue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,13 +419,7 @@ void LedDevicePhilipsHueBridge::log(const char* msg, const char* type, ...) cons

QJsonDocument LedDevicePhilipsHueBridge::getAllBridgeInfos()
{
// Read Groups/ Lights and Light-Ids
_restApi->setPath(API_ROOT);

httpResponse response = _restApi->get();
checkApiError(response.getBody());

return response.getBody();
return get(API_ROOT);
}

bool LedDevicePhilipsHueBridge::initMaps()
Expand Down Expand Up @@ -628,6 +622,15 @@ bool LedDevicePhilipsHueBridge::checkApiError(const QJsonDocument &response)
return apiError;
}

QJsonDocument LedDevicePhilipsHueBridge::get(const QString& route)
{
_restApi->setPath(route);

httpResponse response = _restApi->get();
checkApiError(response.getBody());
return response.getBody();
}

QJsonDocument LedDevicePhilipsHueBridge::post(const QString& route, const QString& content)
{
_restApi->setPath(route);
Expand All @@ -637,6 +640,12 @@ QJsonDocument LedDevicePhilipsHueBridge::post(const QString& route, const QStrin
return response.getBody();
}

QJsonDocument LedDevicePhilipsHueBridge::getLightState(unsigned int lightId)
{
DebugIf( verbose, _log, "GetLightState [%u]", lightId );
return get( QString("%1/%2").arg( API_LIGHTS ).arg( lightId ) );
}

void LedDevicePhilipsHueBridge::setLightState(unsigned int lightId, const QString &state)
{
DebugIf( verbose, _log, "SetLightState [%u]: %s", lightId, QSTRING_CSTR(state) );
Expand All @@ -645,10 +654,8 @@ void LedDevicePhilipsHueBridge::setLightState(unsigned int lightId, const QStrin

QJsonDocument LedDevicePhilipsHueBridge::getGroupState(unsigned int groupId)
{
_restApi->setPath( QString("%1/%2").arg( API_GROUPS ).arg( groupId ) );
httpResponse response = _restApi->get();
checkApiError(response.getBody());
return response.getBody();
DebugIf( verbose, _log, "GetGroupState [%u]", groupId );
return get( QString("%1/%2").arg( API_GROUPS ).arg( groupId ) );
}

QJsonDocument LedDevicePhilipsHueBridge::setGroupState(unsigned int groupId, bool state)
Expand Down Expand Up @@ -712,8 +719,6 @@ PhilipsHueLight::PhilipsHueLight(Logger* log, unsigned int id, QJsonObject value
_colorBlack = {0.0, 0.0, 0.0};
}

saveOriginalState(values);

_lightname = values["name"].toString().trimmed().replace("\"", "");
Info(_log, "Light ID %d (\"%s\", LED index \"%d\") created", id, QSTRING_CSTR(_lightname), ledidx );
}
Expand Down Expand Up @@ -806,7 +811,6 @@ LedDevicePhilipsHue::LedDevicePhilipsHue(const QJsonObject& deviceConfig)
, _switchOffOnBlack(false)
, _brightnessFactor(1.0)
, _transitionTime(1)
, _lightStatesRestored(false)
, _isInitLeds(false)
, _lightsCount(0)
, _groupId(0)
Expand Down Expand Up @@ -1277,42 +1281,54 @@ void LedDevicePhilipsHue::stop()
}

int LedDevicePhilipsHue::open()
{
int retval = 0;
_isDeviceReady = true;

return retval;
}

int LedDevicePhilipsHue::close()
{
int retval = -1;
_isDeviceReady = false;

if( _useHueEntertainmentAPI )
retval = LedDevicePhilipsHueBridge::close();

return retval;
}

bool LedDevicePhilipsHue::switchOn()
{
if ( openStream() )
Debug(_log, "");

bool rc = false;

if ( _isOn )
{
// Everything is OK, device is ready
_isDeviceReady = true;
retval = 0;
rc = true;
}
else
{
// TODO: Stop device (or fallback to classic mode) - suggest to stop device to meet user expectation
//_useHueEntertainmentAPI = false; -to be removed, if 1
// Everything is OK, device is ready
if ( _isEnabled && _isDeviceInitialised )
{
storeState();

if ( _useHueEntertainmentAPI)
{
if ( openStream() )
{
_isOn = true;
rc = true;
}
}
else
else if ( powerOn() )
{
// Classic mode, everything is OK, device is ready
_isDeviceReady = true;
retval = 0;
_isOn = true;
rc = true;
}
}

return retval;
}

int LedDevicePhilipsHue::close()
{
int retval = -1;

retval = LedDevicePhilipsHueBridge::close();

return retval;
return rc;
}

bool LedDevicePhilipsHue::switchOff()
Expand All @@ -1322,7 +1338,10 @@ bool LedDevicePhilipsHue::switchOff()
this->stopBlackTimeoutTimer();

stop_retry_left = 3;
if (_useHueEntertainmentAPI)
{
stopStream();
}

return LedDevicePhilipsHueBridge::switchOff();
}
Expand Down Expand Up @@ -1563,11 +1582,14 @@ bool LedDevicePhilipsHue::storeState()

if ( _isRestoreOrigState )
{
// Save device's original state
//_orignalStateValues = get device's state;

// TODO: Move saveOriginalState out of the HueLight constructor,
// as the light state may have change since last close and needs to be stored again before reopen
if( !_lightIds.empty() )
{
for ( PhilipsHueLight& light : _lights )
{
QJsonObject values = getLightState(light.getId()).object();
light.saveOriginalState(values);
}
}
}

return rc;
Expand All @@ -1577,11 +1599,9 @@ bool LedDevicePhilipsHue::restoreState()
{
bool rc = true;

if ( _isRestoreOrigState && !_lightStatesRestored )
if ( _isRestoreOrigState )
{
// Restore device's original state
_lightStatesRestored = true;

if( !_lightIds.empty() )
{
for ( PhilipsHueLight& light : _lights )
Expand Down
19 changes: 14 additions & 5 deletions libsrc/leddevice/dev_net/LedDevicePhilipsHue.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,11 @@ class PhilipsHueLight
/// @return the color space of the light determined by the model id reported by the bridge.
CiColorTriangle getColorSpace() const;

void saveOriginalState(const QJsonObject& values);
QString getOriginalState() const;

private:

void saveOriginalState(const QJsonObject& values);

Logger* _log;
/// light id
unsigned int _id;
Expand Down Expand Up @@ -200,12 +199,23 @@ class LedDevicePhilipsHueBridge : public ProviderUdpSSL
bool initRestAPI(const QString &hostname, int port, const QString &token );

///
/// @param route the route of the POST request.
/// @brief Perform a REST-API GET
///
/// @param route the route of the GET request.
///
/// @return the content of the GET request.
///
QJsonDocument get(const QString& route);

///
/// @brief Perform a REST-API POST
///
/// @param route the route of the POST request.
/// @param content the content of the POST request.
///
QJsonDocument post(const QString& route, const QString& content);

QJsonDocument getLightState(unsigned int lightId);
void setLightState(unsigned int lightId = 0, const QString &state = "");

QMap<quint16,QJsonObject> getLightMap() const;
Expand Down Expand Up @@ -421,7 +431,7 @@ public slots:
///
/// @return True if success
///
//bool switchOn() override;
bool switchOn() override;

///
/// @brief Switch the LEDs off.
Expand Down Expand Up @@ -525,7 +535,6 @@ private slots:
/// The default of the Hue lights is 400 ms, but we may want it snappier.
int _transitionTime;

bool _lightStatesRestored;
bool _isInitLeds;

/// Array of the light ids.
Expand Down