Skip to content

Commit

Permalink
Add current movie support
Browse files Browse the repository at this point in the history
  • Loading branch information
Pavion committed Dec 4, 2021
1 parent 437d3b2 commit bba48dc
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 26 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ _You need to manually specify the IP address of the Twinkly controller_
| brightness | Dimmer | Adjust brightness |
| mode | String | Set current mode |
| currenteffect | Number | Set current effect for effect mode |
| currentmovie | Number | Set current movie for movie mode |

## Textual configuration example

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class TwinklyTreeBindingConstants {
public static final String CHANNEL_DIMMER = "dimmer";
public static final String CHANNEL_MODE = "mode";
public static final String CHANNEL_CURRENT_EFFECT = "currenteffect";
public static final String CHANNEL_CURRENT_MOVIE = "currentmovie";

public static final String MODE_OFF = "off";
public static final String MODE_COLOR = "color";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.PercentType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
Expand Down Expand Up @@ -100,7 +101,7 @@ public void handleCommand(ChannelUID channelUID, Command command) {
}
break;
case CHANNEL_MODE:
if (command instanceof RefreshType) {
if (command instanceof RefreshType || command.toFullString().toUpperCase().equals("REFRESH")) {
updateState(channelUID, new StringType(getMode()));
} else {
setMode(command.toFullString());
Expand All @@ -114,12 +115,19 @@ public void handleCommand(ChannelUID channelUID, Command command) {
setCurrentEffect(type.intValue());
}
break;
case CHANNEL_CURRENT_MOVIE:
if (command instanceof RefreshType) {
updateState(channelUID, new DecimalType(getCurrentMovie()));
} else {
DecimalType type = (DecimalType) command;
setCurrentMovie(type.intValue());
}
break;
}

} catch (IOException e) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
"Could not control device at IP address " + config.host);
logger.error("Error communicating with Twinkly", e);
logger.error("Error communicating with Twinkly"/* , e */);
config.token = null;
}
}
Expand Down Expand Up @@ -152,20 +160,31 @@ private void setMode(String newMode) throws IOException, ProtocolException, Malf
}

private int getCurrentEffect() throws IOException, ProtocolException, MalformedURLException {
JSONObject getModeResponse = sendRequest(new URL(config.getBaseURL(), "/xled/v1/led/effects/current"), "GET",
null, config.token);
if (getModeResponse.has("preset_id")) {
return getModeResponse.getInt("preset_id");
JSONObject response = sendRequest(new URL(config.getBaseURL(), "/xled/v1/led/effects/current"), "GET", null,
config.token);
if (response.has("preset_id")) {
return response.getInt("preset_id");
} else {
return getModeResponse.getInt("effect_id");
return response.getInt("effect_id");
}
}

private void setCurrentEffect(int currentEffect) throws IOException, ProtocolException, MalformedURLException {
JSONObject setModeResponse = sendRequest(new URL(config.getBaseURL(), "/xled/v1/led/effects/current"), "POST",
JSONObject response = sendRequest(new URL(config.getBaseURL(), "/xled/v1/led/effects/current"), "POST",
"{\"preset_id\":\"" + currentEffect + "\",\"effect_id\":\"" + currentEffect + "\"}", config.token);
}

private int getCurrentMovie() throws IOException, ProtocolException, MalformedURLException {
JSONObject response = sendRequest(new URL(config.getBaseURL(), "/xled/v1/movies/current"), "GET", null,
config.token);
return response.getInt("id");
}

private void setCurrentMovie(int currentMovie) throws IOException, ProtocolException, MalformedURLException {
JSONObject response = sendRequest(new URL(config.getBaseURL(), "/xled/v1/movies/current"), "POST",
"{\"id\":" + currentMovie + "}", config.token);
}

private void logout() {
updateStatus(ThingStatus.OFFLINE);
try {
Expand Down Expand Up @@ -205,7 +224,7 @@ public void initialize() {
// Example for background initialization:
// scheduler.execute(() -> {
// login();
pollingJob = scheduler.scheduleWithFixedDelay(this::refreshState, 100, 1, TimeUnit.MINUTES);
pollingJob = scheduler.scheduleWithFixedDelay(this::refreshState, 0, 1, TimeUnit.MINUTES);
// if (token != null) {
// updateStatus(ThingStatus.ONLINE);
// } else {
Expand All @@ -223,24 +242,30 @@ public void initialize() {
}

private void refreshState() {
try {
refreshIfNeeded();

boolean isOn = isOn();
updateState(CHANNEL_SWITCH, isOn ? OnOffType.ON : OnOffType.OFF);

int brightnessPct = 0;
if (isOn) {
brightnessPct = getBrightness();
}
updateState(CHANNEL_DIMMER, new PercentType(brightnessPct));
} catch (IOException e) {
config.token = null;
logger.error("Issue while polling for state ", e);
for (Channel channel : this.getThing().getChannels()) {
handleCommand(channel.getUID(), RefreshType.REFRESH);
}
/*
*
* try {
* refreshIfNeeded();
*
* boolean isOn = isOn();
* updateState(CHANNEL_SWITCH, isOn ? OnOffType.ON : OnOffType.OFF);
*
* int brightnessPct = 0;
* if (isOn) {
* brightnessPct = getBrightness();
* }
* updateState(CHANNEL_DIMMER, new PercentType(brightnessPct));
* } catch (IOException e) {
* config.token = null;
* logger.error("Issue while polling for state ", e);
* }
*/
}

private void login() {
private synchronized void login() {
try {
config.token = null;

Expand Down Expand Up @@ -271,7 +296,25 @@ private boolean isTokenExpired() {
return config.tokenExpiryDate.before(new Date());
}

private JSONObject sendRequest(URL loginURL, String httpMethod, @Nullable String requestString,
private synchronized JSONObject sendRequest(URL loginURL, String httpMethod, @Nullable String requestString,
@Nullable String token) throws ProtocolException {
JSONObject ret;
try {
ret = sendRequestWrapped(loginURL, httpMethod, requestString, token);
} catch (IOException ex) {
logger.debug("Invalid Token, attempting to reconnect");
login();
try {
ret = sendRequestWrapped(loginURL, httpMethod, requestString, config.token);
} catch (IOException ex2) {
logger.error("Attempt to reconnect failed with an exception: ", ex2);
ret = new JSONObject();
}
}
return ret;
}

private synchronized JSONObject sendRequestWrapped(URL loginURL, String httpMethod, @Nullable String requestString,
@Nullable String token) throws IOException, ProtocolException {
byte[] out = null;
HttpURLConnection connection = (HttpURLConnection) loginURL.openConnection();
Expand Down
6 changes: 6 additions & 0 deletions src/main/resources/OH-INF/thing/thing-types.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<channel id="dimmer" typeId="dimmer"/>
<channel id="mode" typeId="mode"/>
<channel id="currenteffect" typeId="currenteffect"/>
<channel id="currentmovie" typeId="currentmovie"/>
</channels>

<config-description>
Expand Down Expand Up @@ -55,4 +56,9 @@
<label>Current Effect</label>
<description>Current effect in effect mode</description>
</channel-type>
<channel-type id="currentmovie">
<item-type>Number</item-type>
<label>Current Movie</label>
<description>Current movie in movie mode</description>
</channel-type>
</thing:thing-descriptions>

0 comments on commit bba48dc

Please sign in to comment.