[androidTV] fix version parsing for newer Philips TV models (#17373)

* [androidTV] fix version parsing for newer Philips TV models

Signed-off-by: Marcel Verpaalen <marcel@verpaalen.com>
Signed-off-by: Ciprian Pascu <contact@ciprianpascu.ro>
This commit is contained in:
Marcel 2024-09-09 14:48:24 +02:00 committed by Ciprian Pascu
parent b5cc85373d
commit bdf780d575
3 changed files with 123 additions and 12 deletions

View File

@ -12,11 +12,12 @@
*/
package org.openhab.binding.androidtv.internal.protocol.philipstv.service;
import static org.openhab.binding.androidtv.internal.AndroidTVBindingConstants.*;
import static org.openhab.binding.androidtv.internal.AndroidTVBindingConstants.CHANNEL_TV_CHANNEL;
import static org.openhab.binding.androidtv.internal.protocol.philipstv.ConnectionManager.OBJECT_MAPPER;
import static org.openhab.binding.androidtv.internal.protocol.philipstv.PhilipsTVBindingConstants.*;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;
@ -39,6 +40,8 @@ import org.openhab.core.types.RefreshType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
/**
* Service for handling commands regarding setting or retrieving the TV channel
*
@ -105,17 +108,22 @@ public class TvChannelService implements PhilipsTVService {
}
private Map<String, String> getAvailableTvChannelListFromTv() throws IOException {
AvailableTvChannelsDTO availableTvChannelsDTO = OBJECT_MAPPER.readValue(
connectionManager.doHttpsGet(GET_AVAILABLE_TV_CHANNEL_LIST_PATH), AvailableTvChannelsDTO.class);
try {
AvailableTvChannelsDTO availableTvChannelsDTO = OBJECT_MAPPER.readValue(
connectionManager.doHttpsGet(GET_AVAILABLE_TV_CHANNEL_LIST_PATH), AvailableTvChannelsDTO.class);
ConcurrentMap<String, String> tvChannelsMap = availableTvChannelsDTO.getChannel().stream()
.collect(Collectors.toConcurrentMap(ChannelDTO::getName, ChannelDTO::getCcid, (c1, c2) -> c1));
ConcurrentMap<String, String> tvChannelsMap = availableTvChannelsDTO.getChannel().stream()
.collect(Collectors.toConcurrentMap(ChannelDTO::getName, ChannelDTO::getCcid, (c1, c2) -> c1));
logger.debug("TV Channels added: {}", tvChannelsMap.size());
if (logger.isTraceEnabled()) {
tvChannelsMap.keySet().forEach(app -> logger.trace("TV Channel found: {}", app));
logger.debug("TV Channels added: {}", tvChannelsMap.size());
if (logger.isTraceEnabled()) {
tvChannelsMap.keySet().forEach(app -> logger.trace("TV Channel found: {}", app));
}
return tvChannelsMap;
} catch (InvalidFormatException e) {
logger.debug("TV Channels loading failed: {}", e.getMessage(), e);
}
return tvChannelsMap;
return Collections.emptyMap();
}
private String getCurrentTvChannel() throws IOException {

View File

@ -37,7 +37,7 @@ public class AvailableTvChannelsDTO {
private String medium = "";
@JsonProperty("version")
private int version;
private String version;
@JsonProperty("listType")
private String listType = "";
@ -75,11 +75,11 @@ public class AvailableTvChannelsDTO {
return medium;
}
public void setVersion(int version) {
public void setVersion(String version) {
this.version = version;
}
public int getVersion() {
public String getVersion() {
return version;
}

View File

@ -0,0 +1,103 @@
/**
* Copyright (c) 2010-2024 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.androidtv.internal.protocol.philipstv.service;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import static org.openhab.binding.androidtv.internal.AndroidTVBindingConstants.CHANNEL_TV_CHANNEL;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import org.openhab.binding.androidtv.internal.protocol.philipstv.ConnectionManager;
import org.openhab.binding.androidtv.internal.protocol.philipstv.PhilipsTVConnectionManager;
import org.openhab.core.library.types.StringType;
import org.openhab.core.types.Command;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The {@link PhilipsTvChannelTest} is responsible for testing {@linkTvChannelService}
*
* @author Marcel Verpaalen - Initial contribution
*
*/
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
@NonNullByDefault
public class PhilipsTvChannelTest {
private final Logger logger = LoggerFactory.getLogger(getClass());
private @Mock @NonNullByDefault({}) PhilipsTVConnectionManager handler;
private @Mock @NonNullByDefault({}) ConnectionManager connectionManager;
static final String NEW_RESPONSE = "{\"version\":\"84384_293_1\",\"id\":\"all\",\"listType\":\"MixedSources\",\"medium\":\"mixed\",\"operator\":\"Ziggo\",\"installCountry\":\"Netherlands\",\"Channel\":[{\"ccid\":142,\"preset\":\"1\",\"name\":\"NPO 1\",\"onid\":1536,\"tsid\":2098,\"sid\":19401,\"serviceType\":\"audio_video\",\"type\":\"DVB_C\",\"logoVersion\":142},{\"ccid\":143,\"preset\":\"2\",\"name\":\"NPO 2\",\"onid\":1536,\"tsid\":2098,\"sid\":19402,\"serviceType\":\"audio_video\",\"type\":\"DVB_C\",\"logoVersion\":143}]}";
static final String OLD_RESPONSE = "{\"version\":123,\"id\":\"all\",\"listType\":\"MixedSources\",\"medium\":\"mixed\",\"operator\":\"Ziggo\",\"installCountry\":\"Netherlands\",\"Channel\":[{\"ccid\":142,\"preset\":\"1\",\"name\":\"NPO 1\",\"onid\":1536,\"tsid\":2098,\"sid\":19401,\"serviceType\":\"audio_video\",\"type\":\"DVB_C\",\"logoVersion\":142},{\"ccid\":143,\"preset\":\"2\",\"name\":\"NPO 2\",\"onid\":1536,\"tsid\":2098,\"sid\":19402,\"serviceType\":\"audio_video\",\"type\":\"DVB_C\",\"logoVersion\":143}]}";
static final String TEST_CHANNEL = "NPO 2";
private void testPhilipsTVChannelParsing(String channel, Command command, String ccid) throws IOException {
Map<String, String> availableTvChannels = Collections.emptyMap();
TvChannelService tvChannelService = new TvChannelService(handler, connectionManager);
tvChannelService.handleCommand(channel, command);
ArgumentCaptor<Map<String, String>> captor = ArgumentCaptor.forClass(Map.class);
verify(handler, atLeastOnce()).updateChannelStateDescription(ArgumentMatchers.eq(CHANNEL_TV_CHANNEL),
captor.capture());
availableTvChannels = captor.getValue();
logger.info("Channels found: {}", availableTvChannels);
assertEquals(2, availableTvChannels.size());
assertEquals(TEST_CHANNEL, availableTvChannels.get(TEST_CHANNEL));
ArgumentCaptor<String> captorSwitchChannel = ArgumentCaptor.forClass(String.class);
verify(connectionManager, atLeastOnce()).doHttpsPost(any(), captorSwitchChannel.capture());
String changeChannelJson = captorSwitchChannel.getValue();
logger.info("Channel change command: {}", changeChannelJson);
assertEquals("{\"channel\":{\"serviceType\":\"\",\"logoVersion\":0,\"ccid\":\"" + ccid
+ "\",\"name\":\"\",\"preset\":\"\",\"tsid\":0,\"type\":\"\",\"onid\":0,\"sid\":0},\"channelList\":{\"id\":\"allter\",\"version\":\"30\"}}",
changeChannelJson);
}
@Test
public void testNewerPhilipsTVChannelParsing() {
try {
// test compatibility with newer Philips TV's that provide the version as string
when(connectionManager.doHttpsGet(any())).thenReturn(NEW_RESPONSE);
testPhilipsTVChannelParsing(TEST_CHANNEL, new StringType(TEST_CHANNEL), "143");
} catch (IOException e) {
logger.warn("Test Failed with", e);
}
}
@Test
public void testOlderPhilipsTVChannelParsing() {
try {
// test compatibility with older Philips TV's that provide the version as int
when(connectionManager.doHttpsGet(any())).thenReturn(OLD_RESPONSE);
testPhilipsTVChannelParsing("NPO 1", new StringType("NPO 1"), "142");
} catch (IOException e) {
logger.warn("Test Failed with", e);
}
}
}