Skip to content
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
1 change: 1 addition & 0 deletions core/api/core.api
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public final class inkapplications/shade/core/Shade {
public final fun getDevices ()Linkapplications/shade/devices/DeviceControls;
public final fun getGroupedLights ()Linkapplications/shade/groupedlights/GroupedLightControls;
public final fun getHomekit ()Linkapplications/shade/homekit/HomekitControls;
public final fun getLightLevels ()Linkapplications/shade/lightlevel/LightLevelControls;
public final fun getLights ()Linkapplications/shade/lights/LightControls;
public final fun getOnlineDiscovery ()Linkapplications/shade/discover/BridgeDiscovery;
public final fun getResources ()Linkapplications/shade/resources/ResourceControls;
Expand Down
1 change: 1 addition & 0 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ kotlin {
api(projects.events)
api(projects.groupedLights)
api(projects.lights)
api(projects.lightlevel)
api(projects.resources)
api(projects.rooms)
api(projects.scenes)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import inkapplications.shade.events.EventsModule
import inkapplications.shade.groupedlights.ShadeGroupedLightsModule
import inkapplications.shade.homekit.ShadeHomekitModule
import inkapplications.shade.internals.InternalsModule
import inkapplications.shade.lightlevel.ShadeLightLevelModule
import inkapplications.shade.lights.ShadeLightsModule
import inkapplications.shade.resources.ShadeResourcesModule
import inkapplications.shade.rooms.ShadeRoomsModule
Expand Down Expand Up @@ -53,6 +54,7 @@ class Shade(
).bridgeAuth
val devices = ShadeDevicesModule(internalsModule).devices
val lights = ShadeLightsModule(internalsModule, eventsModule).lights
val lightLevels = ShadeLightLevelModule(internalsModule).lightLevels
val rooms = ShadeRoomsModule(internalsModule).rooms
val zones = ShadeZonesModule(internalsModule).zones
val groupedLights = ShadeGroupedLightsModule(internalsModule, eventsModule).groupedLights
Expand Down
134 changes: 134 additions & 0 deletions lightlevel/api/lightlevel.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
public abstract interface class inkapplications/shade/lightlevel/LightLevelControls {
public abstract fun getLightLevel-klA6Vuc (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public abstract fun listLightLevels (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public abstract fun updateLightLevel-bKh5c1I (Ljava/lang/String;Linkapplications/shade/lightlevel/parameters/LightLevelUpdateParameters;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
}

public final class inkapplications/shade/lightlevel/ShadeLightLevelModule {
public fun <init> (Linkapplications/shade/internals/InternalsModule;)V
public final fun getLightLevels ()Linkapplications/shade/lightlevel/LightLevelControls;
}

public final class inkapplications/shade/lightlevel/parameters/LightLevelUpdateParameters {
public static final field Companion Linkapplications/shade/lightlevel/parameters/LightLevelUpdateParameters$Companion;
public fun <init> ()V
public fun <init> (Ljava/lang/Boolean;)V
public synthetic fun <init> (Ljava/lang/Boolean;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Ljava/lang/Boolean;
public final fun copy (Ljava/lang/Boolean;)Linkapplications/shade/lightlevel/parameters/LightLevelUpdateParameters;
public static synthetic fun copy$default (Linkapplications/shade/lightlevel/parameters/LightLevelUpdateParameters;Ljava/lang/Boolean;ILjava/lang/Object;)Linkapplications/shade/lightlevel/parameters/LightLevelUpdateParameters;
public fun equals (Ljava/lang/Object;)Z
public final fun getEnabled ()Ljava/lang/Boolean;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final synthetic class inkapplications/shade/lightlevel/parameters/LightLevelUpdateParameters$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
public static final field INSTANCE Linkapplications/shade/lightlevel/parameters/LightLevelUpdateParameters$$serializer;
public final fun childSerializers ()[Lkotlinx/serialization/KSerializer;
public final fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Linkapplications/shade/lightlevel/parameters/LightLevelUpdateParameters;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public final fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Linkapplications/shade/lightlevel/parameters/LightLevelUpdateParameters;)V
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
}

public final class inkapplications/shade/lightlevel/parameters/LightLevelUpdateParameters$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

public final class inkapplications/shade/lightlevel/structures/LightLevel {
public static final field Companion Linkapplications/shade/lightlevel/structures/LightLevel$Companion;
public synthetic fun <init> (Ljava/lang/String;Linkapplications/shade/structures/ResourceReference;ZLinkapplications/shade/lightlevel/structures/LightLevelValue;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Ljava/lang/String;Linkapplications/shade/structures/ResourceReference;ZLinkapplications/shade/lightlevel/structures/LightLevelValue;Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1-XbiYvy0 ()Ljava/lang/String;
public final fun component2 ()Linkapplications/shade/structures/ResourceReference;
public final fun component3 ()Z
public final fun component4 ()Linkapplications/shade/lightlevel/structures/LightLevelValue;
public final fun component5-1y3a6N0 ()Ljava/lang/String;
public final fun copy-qm0Ps9A (Ljava/lang/String;Linkapplications/shade/structures/ResourceReference;ZLinkapplications/shade/lightlevel/structures/LightLevelValue;Ljava/lang/String;)Linkapplications/shade/lightlevel/structures/LightLevel;
public static synthetic fun copy-qm0Ps9A$default (Linkapplications/shade/lightlevel/structures/LightLevel;Ljava/lang/String;Linkapplications/shade/structures/ResourceReference;ZLinkapplications/shade/lightlevel/structures/LightLevelValue;Ljava/lang/String;ILjava/lang/Object;)Linkapplications/shade/lightlevel/structures/LightLevel;
public fun equals (Ljava/lang/Object;)Z
public final fun getEnabled ()Z
public final fun getId-XbiYvy0 ()Ljava/lang/String;
public final fun getLight ()Linkapplications/shade/lightlevel/structures/LightLevelValue;
public final fun getOwner ()Linkapplications/shade/structures/ResourceReference;
public final fun getType-1y3a6N0 ()Ljava/lang/String;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final synthetic class inkapplications/shade/lightlevel/structures/LightLevel$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
public static final field INSTANCE Linkapplications/shade/lightlevel/structures/LightLevel$$serializer;
public final fun childSerializers ()[Lkotlinx/serialization/KSerializer;
public final fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Linkapplications/shade/lightlevel/structures/LightLevel;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public final fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Linkapplications/shade/lightlevel/structures/LightLevel;)V
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
}

public final class inkapplications/shade/lightlevel/structures/LightLevel$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

public final class inkapplications/shade/lightlevel/structures/LightLevelReport {
public static final field Companion Linkapplications/shade/lightlevel/structures/LightLevelReport$Companion;
public fun <init> (Lkotlin/time/Instant;Linkapplications/shade/structures/Illuminance;)V
public final fun component1 ()Lkotlin/time/Instant;
public final fun component2 ()Linkapplications/shade/structures/Illuminance;
public final fun copy (Lkotlin/time/Instant;Linkapplications/shade/structures/Illuminance;)Linkapplications/shade/lightlevel/structures/LightLevelReport;
public static synthetic fun copy$default (Linkapplications/shade/lightlevel/structures/LightLevelReport;Lkotlin/time/Instant;Linkapplications/shade/structures/Illuminance;ILjava/lang/Object;)Linkapplications/shade/lightlevel/structures/LightLevelReport;
public fun equals (Ljava/lang/Object;)Z
public final fun getChanged ()Lkotlin/time/Instant;
public final fun getLightLevel ()Linkapplications/shade/structures/Illuminance;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final synthetic class inkapplications/shade/lightlevel/structures/LightLevelReport$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
public static final field INSTANCE Linkapplications/shade/lightlevel/structures/LightLevelReport$$serializer;
public final fun childSerializers ()[Lkotlinx/serialization/KSerializer;
public final fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Linkapplications/shade/lightlevel/structures/LightLevelReport;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public final fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Linkapplications/shade/lightlevel/structures/LightLevelReport;)V
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
}

public final class inkapplications/shade/lightlevel/structures/LightLevelReport$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

public final class inkapplications/shade/lightlevel/structures/LightLevelValue {
public static final field Companion Linkapplications/shade/lightlevel/structures/LightLevelValue$Companion;
public fun <init> ()V
public fun <init> (Linkapplications/shade/lightlevel/structures/LightLevelReport;)V
public synthetic fun <init> (Linkapplications/shade/lightlevel/structures/LightLevelReport;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Linkapplications/shade/lightlevel/structures/LightLevelReport;
public final fun copy (Linkapplications/shade/lightlevel/structures/LightLevelReport;)Linkapplications/shade/lightlevel/structures/LightLevelValue;
public static synthetic fun copy$default (Linkapplications/shade/lightlevel/structures/LightLevelValue;Linkapplications/shade/lightlevel/structures/LightLevelReport;ILjava/lang/Object;)Linkapplications/shade/lightlevel/structures/LightLevelValue;
public fun equals (Ljava/lang/Object;)Z
public final fun getLightLevelReport ()Linkapplications/shade/lightlevel/structures/LightLevelReport;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final synthetic class inkapplications/shade/lightlevel/structures/LightLevelValue$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
public static final field INSTANCE Linkapplications/shade/lightlevel/structures/LightLevelValue$$serializer;
public final fun childSerializers ()[Lkotlinx/serialization/KSerializer;
public final fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Linkapplications/shade/lightlevel/structures/LightLevelValue;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public final fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Linkapplications/shade/lightlevel/structures/LightLevelValue;)V
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
}

public final class inkapplications/shade/lightlevel/structures/LightLevelValue$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

28 changes: 28 additions & 0 deletions lightlevel/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
plugins {
id("library")
kotlin("plugin.serialization")
id("ink.publishing")
}

kotlin {
sourceSets {
val commonMain by getting {
dependencies {
implementation(libs.serialization.json)
implementation(projects.internals)
implementation(projects.serialization)
api(projects.structures)

api(libs.coroutines.core)
}
}

val commonTest by getting {
dependencies {
implementation(libs.test.core)
implementation(libs.test.annotations)
}
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package inkapplications.shade.lightlevel

import inkapplications.shade.lightlevel.parameters.LightLevelUpdateParameters
import inkapplications.shade.lightlevel.structures.LightLevel
import inkapplications.shade.structures.ResourceId
import inkapplications.shade.structures.ResourceReference

/**
* Actions to get light level sensor data from the hue system.
*/
interface LightLevelControls {
/**
* Get a list of light level sensors configured on the hue service.
*
* @return A list of all light level sensors configured on the bridge.
*/
suspend fun listLightLevels(): List<LightLevel>

/**
* Get the state of a single light level sensor.
*
* @param id The resource ID of the light level sensor to fetch data about.
* @return State and capability information about the light level sensor.
*/
suspend fun getLightLevel(id: ResourceId): LightLevel

/**
* Update a light level sensor on the hue bridge.
*
* @param id The resource ID of the light level sensor to be updated.
* @param parameters Data about the light level sensor to be updated.
* @return A reference to the updated resource.
*/
suspend fun updateLightLevel(id: ResourceId, parameters: LightLevelUpdateParameters): ResourceReference
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package inkapplications.shade.lightlevel

import inkapplications.shade.internals.HueHttpClient
import inkapplications.shade.internals.getData
import inkapplications.shade.internals.putData
import inkapplications.shade.lightlevel.parameters.LightLevelUpdateParameters
import inkapplications.shade.lightlevel.structures.LightLevel
import inkapplications.shade.structures.ResourceId
import inkapplications.shade.structures.ResourceReference

/**
* Implements light level sensor controls via the hue client.
*/
internal class ShadeLightLevel(
private val hueHttpClient: HueHttpClient,
): LightLevelControls {
override suspend fun listLightLevels(): List<LightLevel> {
return hueHttpClient.getData("resource", "light_level")
}

override suspend fun getLightLevel(id: ResourceId): LightLevel {
return hueHttpClient.getData<List<LightLevel>>("resource", "light_level", id.value).single()
}

override suspend fun updateLightLevel(
id: ResourceId,
parameters: LightLevelUpdateParameters
): ResourceReference {
val response: List<ResourceReference> = hueHttpClient.putData(
body = parameters,
pathSegments = arrayOf("resource", "light_level", id.value),
)

return response.single()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package inkapplications.shade.lightlevel

import inkapplications.shade.internals.InternalsModule

/**
* Provides access to light level sensor services.
*
* These are offered by devices with light level sensing capabilities.
*/
class ShadeLightLevelModule(
internalsModule: InternalsModule,
) {
val lightLevels: LightLevelControls = ShadeLightLevel(internalsModule.hueHttpClient)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package inkapplications.shade.lightlevel.parameters

import kotlinx.serialization.Serializable

/**
* Parameters that can be specified when updating a light level sensor.
*/
@Serializable
data class LightLevelUpdateParameters(
/**
* Whether the sensor is activated.
*
* true when sensor is activated, false when deactivated.
*/
val enabled: Boolean? = null,
)

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package inkapplications.shade.lightlevel.structures

import inkapplications.shade.structures.ResourceId
import inkapplications.shade.structures.ResourceReference
import inkapplications.shade.structures.ResourceType
import kotlinx.serialization.Serializable

/**
* State and capabilities of a light level sensor resource.
*/
@Serializable
data class LightLevel(
/**
* Unique identifier representing a specific light level sensor instance.
*/
val id: ResourceId,

/**
* Owner of the service.
*
* In case the owner service is deleted, the service also gets deleted.
*/
val owner: ResourceReference,

/**
* Whether the sensor is activated.
*
* true when sensor is activated, false when deactivated.
*/
val enabled: Boolean,

/**
* Light level sensor data.
*/
val light: LightLevelValue,

/**
* Type of the supported resource.
*/
val type: ResourceType = ResourceType.LightLevel,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package inkapplications.shade.lightlevel.structures

import inkapplications.shade.structures.Illuminance
import inkapplications.shade.structures.ScaledLuxSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlin.time.Instant

/**
* Report containing light level sensor data.
*/
@Serializable
data class LightLevelReport(
/**
* Last time the value of this property was changed.
*/
val changed: Instant,

/**
* Light level measured by sensor.
*/
@SerialName("light_level")
@Serializable(with = ScaledLuxSerializer::class)
val lightLevel: Illuminance,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package inkapplications.shade.lightlevel.structures

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

/**
* Light level sensor data.
*/
@Serializable
data class LightLevelValue(
/**
* Detailed light level report with timestamp.
*/
@SerialName("light_level_report")
val lightLevelReport: LightLevelReport? = null,
)
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ include("events")
include("grouped-lights")
include("homekit")
include("internals")
include("lightlevel")
include("lights")
include("resources")
include("rooms")
Expand Down
Loading