package shelly include ShellySwitch.feather include ShellyBehaviour.feather import java.net.URI import java.net.http.* import java.net.http.HttpRequest.BodyPublishers import java.net.http.HttpResponse.BodyHandlers /** * Operates Shelly switches. * * See https://shelly-api-docs.shelly.cloud/gen2/0.14/ComponentsAndServices/Switch/#switchset * */ class Shelly : SimpleComponent() { class val SHELLY_SWITCH = "ShellySwitch" // Context type, with value of ShellySwitch // ==== Register ==== override meth register() { addFeatures( SHELLY_SWITCH ).apply { val toggle = contextAction( "Toggle", ::toggleAction ) val on = contextAction( "On", ::setAction.curry(true) ) val off = contextAction( "Off", ::setAction.curry(false) ) contextMenu( on, off, toggle ) } } // ==== Actions ==== func toggleAction( context : Context ) { (context.value as ShellySwitch).toggle() } func setAction( on : bool, context : Context ) { (context.value as ShellySwitch).set( on ) } // ==== API ==== func toggle( address : String, id : int ) : HttpResponse { val uri = "http://$address/rpc" val message = """{"id":$id,"method":"Switch.Toggle","params":{"id":$id}}""" return httpPostString( uri, message ) } func toggleAsync( address : String, id : int ) { val uri = "http://$address/rpc" val message = """{"id":$id,"method":"Switch.Toggle","params":{"id":$id}}""" httpPostStringAsync( uri, message ) } func set( address : String, id : int, on : bool ) : HttpResponse { val uri = "http://$address/rpc" val message = """{"id":$id,"method":"Switch.Set","params":{"id":$id, "on":$on}}""" return httpPostString( uri, message ) } func setAsync( address : String, id : int, on : bool ) { val uri = "http://$address/rpc" val message = """{"id":$id,"method":"Switch.Set","params":{"id":$id, "on":$on}}""" httpPostStringAsync( uri, message ) } func getStatus( address : String, id : int ) : HttpResponse { val uri = "http://$address/rpc" val message = """{"id":$id,"method":"Switch.GetStatus","params":{"id":$id}}""" return httpPostString( uri, message ) } func httpPostString( uri : String, message : String ) : HttpResponse { val client = HttpClient.newHttpClient() val request = HttpRequest.newBuilder() .uri(URI.create(uri)) .POST(BodyPublishers.ofString(message)) .build() return client.send(request, BodyHandlers.ofString()) } func httpPostStringAsync(uri: String, message: String) { val client = HttpClient.newHttpClient() val request = HttpRequest.newBuilder() .uri(URI.create(uri)) .POST(BodyPublishers.ofString(message)) .build() client.sendAsync(request, BodyHandlers.ofString()) } }