package io.homeassistant.android.api;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Pair;
import com.afollestad.ason.Ason;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import io.homeassistant.android.api.results.Entity;
import io.homeassistant.android.api.results.EventData;
import static io.homeassistant.android.api.Domain.AUTOMATION;
import static io.homeassistant.android.api.Domain.BINARY_SENSOR;
import static io.homeassistant.android.api.Domain.CAMERA;
import static io.homeassistant.android.api.Domain.CLIMATE;
import static io.homeassistant.android.api.Domain.COVER;
import static io.homeassistant.android.api.Domain.DEVICE_TRACKER;
import static io.homeassistant.android.api.Domain.GROUP;
import static io.homeassistant.android.api.Domain.INPUT_BOOLEAN;
import static io.homeassistant.android.api.Domain.INPUT_SELECT;
import static io.homeassistant.android.api.Domain.LIGHT;
import static io.homeassistant.android.api.Domain.LOCK;
import static io.homeassistant.android.api.Domain.SCENE;
import static io.homeassistant.android.api.Domain.SENSOR;
import static io.homeassistant.android.api.Domain.SUN;
import static io.homeassistant.android.api.Domain.SWITCH;
public final class HassUtils {
private HassUtils() {
}
/**
* Extract entities from a RequestResult of a StateRequest
*
* @param result the RequestResult to extract from
* @param entityMap the Map where entities are store with their id as key
* @return true if items were added, else false
*/
public static boolean extractEntitiesFromStateResult(@Nullable Object result, @NonNull Map<String, Entity> entityMap) {
if (result != null && result.getClass().isArray()) {
// Clear map before adding new content
entityMap.clear();
for (Object o : (Object[]) result) {
Entity entity = Ason.deserialize((Ason) o, Entity.class);
entity.applyType();
entityMap.put(entity.id, entity);
}
return true;
}
return false;
}
/**
* Extract an updated entity from an event and update the entityMap with the new state
*
* @param result the EventData to extract from
* @param entityMap the Map where entities are store with their id as key
* @return true if items were updated, else false
*/
@Nullable
public static Entity updateEntityFromEventResult(@Nullable EventData result, @NonNull Map<String, Entity> entityMap) {
if (result != null) {
Entity current = entityMap.get(result.entity_id);
Entity updated = result.new_state;
current.state = updated.state;
current.attributes = updated.attributes;
current.last_changed = updated.last_changed;
current.last_updated = updated.last_updated;
return current;
}
return null;
}
public static void extractGroups(@NonNull Map<String, Entity> entityMap, List<Pair<Entity, List<Entity>>> entities) {
entities.clear();
for (Entity entity : entityMap.values()) {
if (entity.getDomain().equals(GROUP)) {
if (entity.isHidden()) {
continue;
}
// Add group children
List<String> entityIds = entity.attributes.getList(Attribute.ENTITY_ID, String.class);
if (entityIds == null) {
continue;
}
List<Entity> children = new ArrayList<>();
for (String childrenKey : entityIds) {
Entity child = entityMap.get(childrenKey);
if (child == null) continue;
if (!child.isHidden()) {
children.add(child);
}
}
entities.add(new Pair<>(entity, children));
}
}
// Sort groups according to their order number
//noinspection Java8ListSort,ComparatorCombinators
Collections.sort(entities, (o1, o2) -> o1.first.compareTo(o2.first));
}
@Nullable
public static String getOnState(@NonNull Entity e, boolean on) {
if (e.type == EntityType.SWITCH) {
if (e.getDomain().equals(LOCK)) {
return on ? "locked" : "unlocked";
} else {
return on ? "on" : "off";
}
} else return null;
}
public static void applyDefaultIcon(@NotNull Entity e) {
if (e.attributes.get(Attribute.ICON) != null || e.attributes.get(Attribute.ENTITY_PICTURE) != null)
return;
String icon;
// For now, include all domains from https://github.com/home-assistant/home-assistant-polymer/blob/master/src/util/hass-util.html#L219,
// even though most are currently not supported by this app.
switch (e.getDomain()) {
case "alarm_control_panel":
icon = e.state != null && e.state.equals("disarmed") ? "mdi:bell-outline" : "mdi:bell";
break;
case AUTOMATION:
icon = "mdi:playlist-play";
break;
case BINARY_SENSOR:
icon = e.state != null && e.state.equals("off") ? "mdi:radiobox-blank" : "mdi:checkbox-marked-circle";
break;
case "calendar":
icon = "mdi:calendar";
break;
case CAMERA:
icon = "mdi:video";
break;
case CLIMATE:
icon = "mdi:nest-thermostat";
break;
case "configurator":
icon = "mdi:settings";
break;
case "conversation":
icon = "mdi:text-to-speech";
break;
case COVER:
icon = e.state != null && e.state.equals("open") ? "mdi:window-open" : "mdi:window-closed";
break;
case DEVICE_TRACKER:
icon = "mdi:account";
break;
case "fan":
icon = "mdi:fan";
break;
case GROUP:
icon = "mdi:google-circles-communities";
break;
case "homeassistant":
icon = "mdi:home";
break;
case "image_processing":
icon = "mdi:image-filter-frames";
break;
case INPUT_BOOLEAN:
icon = "mdi:drawing";
break;
case INPUT_SELECT:
icon = "mdi:format-list-bulleted";
break;
case "input_slider":
icon = "mdi:ray-vertex";
break;
case LIGHT:
icon = "mdi:lightbulb";
break;
case LOCK:
icon = e.state != null && e.state.equals("unlocked") ? "mdi:lock-open" : "mdi:lock";
break;
case "media_player":
icon = e.state != null && !e.state.equals("off") && !e.state.equals("idle") ? "mdi:cast-connected" : "mdi:cast";
break;
case "notify":
icon = "mdi:comment-alert";
break;
case "proximity":
icon = "mdi:apple-safari";
break;
case "remote":
icon = "mdi:remote";
break;
case SCENE:
icon = "mdi:google-pages";
break;
case "script":
icon = "mdi:file-document";
break;
case SENSOR:
icon = "mdi:eye";
break;
case "simple_alarm":
icon = "mdi:bell";
break;
case SUN:
icon = "mdi:white-balance-sunny";
e.state = e.state.replace('_', ' ');
break;
case SWITCH:
icon = "mdi:flash";
break;
case "updater":
icon = "mdi:cloud-upload";
break;
case "weblink":
icon = "mdi:open-in-new";
break;
default:
icon = null;
break;
}
e.attributes.put(Attribute.ICON, icon);
}
}