Skip to content

Commit 2d01518

Browse files
committed
[rest] Support sending Item command/state as JSON (openhab#4760)
Signed-off-by: Florian Hotze <[email protected]> (cherry picked from commit 8ff69a3)
1 parent 50fb5c9 commit 2d01518

File tree

1 file changed

+45
-10
lines changed
  • bundles/org.openhab.core.io.rest.core/src/main/java/org/openhab/core/io/rest/core/internal/item

1 file changed

+45
-10
lines changed

bundles/org.openhab.core.io.rest.core/src/main/java/org/openhab/core/io/rest/core/internal/item/ItemResource.java

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,15 @@
104104
import org.slf4j.Logger;
105105
import org.slf4j.LoggerFactory;
106106

107+
import com.google.gson.Gson;
107108
import com.google.gson.JsonObject;
108109

109110
import io.swagger.v3.oas.annotations.Operation;
110111
import io.swagger.v3.oas.annotations.Parameter;
111112
import io.swagger.v3.oas.annotations.media.ArraySchema;
112113
import io.swagger.v3.oas.annotations.media.Content;
113114
import io.swagger.v3.oas.annotations.media.Schema;
115+
import io.swagger.v3.oas.annotations.parameters.RequestBody;
114116
import io.swagger.v3.oas.annotations.responses.ApiResponse;
115117
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
116118
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -172,6 +174,7 @@ private static void respectForwarded(final UriBuilder uriBuilder, final @Context
172174
}
173175

174176
private final Logger logger = LoggerFactory.getLogger(ItemResource.class);
177+
private final Gson gson = new Gson();
175178

176179
private final DTOMapper dtoMapper;
177180
private final EventPublisher eventPublisher;
@@ -422,14 +425,29 @@ public Response getBinaryItemState(@HeaderParam("Accept") @Nullable String media
422425
@RolesAllowed({ Role.USER, Role.ADMIN })
423426
@Path("/{itemname: [a-zA-Z_0-9]+}/state")
424427
@Consumes(MediaType.TEXT_PLAIN)
425-
@Operation(operationId = "updateItemState", summary = "Updates the state of an item.", responses = {
426-
@ApiResponse(responseCode = "202", description = "Accepted"),
427-
@ApiResponse(responseCode = "404", description = "Item not found"),
428-
@ApiResponse(responseCode = "400", description = "Item state null") })
429-
public Response putItemState(
428+
@Operation(operationId = "updateItemState", summary = "Updates the state of an item.", requestBody = @RequestBody(description = "Valid item state (e.g., ON, OFF) either as plain text or JSON", required = true, content = {
429+
@Content(mediaType = MediaType.TEXT_PLAIN, schema = @Schema(type = "string", example = "ON")),
430+
@Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(type = "string", example = "{ \"value\": \"ON\" }")) }), responses = {
431+
@ApiResponse(responseCode = "202", description = "Accepted"),
432+
@ApiResponse(responseCode = "404", description = "Item not found"),
433+
@ApiResponse(responseCode = "400", description = "State cannot be parsed") })
434+
public Response putItemStatePlain(
430435
@HeaderParam(HttpHeaders.ACCEPT_LANGUAGE) @Parameter(description = "language") @Nullable String language,
431436
@PathParam("itemname") @Parameter(description = "item name") String itemname,
432437
@Parameter(description = "valid item state (e.g. ON, OFF)", required = true) String value) {
438+
return sendItemStateInternal(language, itemname, value);
439+
}
440+
441+
@PUT
442+
@RolesAllowed({ Role.USER, Role.ADMIN })
443+
@Path("/{itemname: [a-zA-Z_0-9]+}/state")
444+
@Consumes(MediaType.APPLICATION_JSON)
445+
public Response putItemStateJson(@HeaderParam(HttpHeaders.ACCEPT_LANGUAGE) @Nullable String language,
446+
@PathParam("itemname") String itemname, ValueContainer valueContainer) {
447+
return sendItemStateInternal(language, itemname, valueContainer.value());
448+
}
449+
450+
private Response sendItemStateInternal(@Nullable String language, String itemname, String value) {
433451
final Locale locale = localeService.getLocale(language);
434452
final ZoneId zoneId = timeZoneProvider.getTimeZone();
435453

@@ -459,12 +477,26 @@ public Response putItemState(
459477
@RolesAllowed({ Role.USER, Role.ADMIN })
460478
@Path("/{itemname: [a-zA-Z_0-9]+}")
461479
@Consumes(MediaType.TEXT_PLAIN)
462-
@Operation(operationId = "sendItemCommand", summary = "Sends a command to an item.", responses = {
463-
@ApiResponse(responseCode = "200", description = "OK"),
464-
@ApiResponse(responseCode = "404", description = "Item not found"),
465-
@ApiResponse(responseCode = "400", description = "Item command null") })
466-
public Response postItemCommand(@PathParam("itemname") @Parameter(description = "item name") String itemname,
480+
@Operation(operationId = "sendItemCommand", summary = "Sends a command to an item.", requestBody = @RequestBody(description = "Valid item command (e.g., ON, OFF) either as plain text or JSON", required = true, content = {
481+
@Content(mediaType = MediaType.TEXT_PLAIN, schema = @Schema(type = "string", example = "ON")),
482+
@Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(type = "string", example = "{ \"value\": \"ON\" }")) }), responses = {
483+
@ApiResponse(responseCode = "200", description = "OK"),
484+
@ApiResponse(responseCode = "404", description = "Item not found"),
485+
@ApiResponse(responseCode = "400", description = "Command cannot be parsed") })
486+
public Response postItemCommandPlain(@PathParam("itemname") @Parameter(description = "item name") String itemname,
467487
@Parameter(description = "valid item command (e.g. ON, OFF, UP, DOWN, REFRESH)", required = true) String value) {
488+
return sendItemCommandInternal(itemname, value);
489+
}
490+
491+
@POST
492+
@RolesAllowed({ Role.USER, Role.ADMIN })
493+
@Path("/{itemname: [a-zA-Z_0-9]+}")
494+
@Consumes(MediaType.APPLICATION_JSON)
495+
public Response postItemCommandJson(@PathParam("itemname") String itemname, ValueContainer valueContainer) {
496+
return sendItemCommandInternal(itemname, valueContainer.value());
497+
}
498+
499+
private Response sendItemCommandInternal(String itemname, String value) {
468500
Item item = getItem(itemname);
469501
Command command = null;
470502
if (item != null) {
@@ -1006,4 +1038,7 @@ private void addMetadata(EnrichedItemDTO dto, Set<String> namespaces, @Nullable
10061038
private boolean isEditable(String itemName) {
10071039
return managedItemProvider.get(itemName) != null;
10081040
}
1041+
1042+
private record ValueContainer(String value) {
1043+
}
10091044
}

0 commit comments

Comments
 (0)