|
104 | 104 | import org.slf4j.Logger;
|
105 | 105 | import org.slf4j.LoggerFactory;
|
106 | 106 |
|
| 107 | +import com.google.gson.Gson; |
107 | 108 | import com.google.gson.JsonObject;
|
108 | 109 |
|
109 | 110 | import io.swagger.v3.oas.annotations.Operation;
|
110 | 111 | import io.swagger.v3.oas.annotations.Parameter;
|
111 | 112 | import io.swagger.v3.oas.annotations.media.ArraySchema;
|
112 | 113 | import io.swagger.v3.oas.annotations.media.Content;
|
113 | 114 | import io.swagger.v3.oas.annotations.media.Schema;
|
| 115 | +import io.swagger.v3.oas.annotations.parameters.RequestBody; |
114 | 116 | import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
115 | 117 | import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
116 | 118 | import io.swagger.v3.oas.annotations.tags.Tag;
|
@@ -172,6 +174,7 @@ private static void respectForwarded(final UriBuilder uriBuilder, final @Context
|
172 | 174 | }
|
173 | 175 |
|
174 | 176 | private final Logger logger = LoggerFactory.getLogger(ItemResource.class);
|
| 177 | + private final Gson gson = new Gson(); |
175 | 178 |
|
176 | 179 | private final DTOMapper dtoMapper;
|
177 | 180 | private final EventPublisher eventPublisher;
|
@@ -422,14 +425,29 @@ public Response getBinaryItemState(@HeaderParam("Accept") @Nullable String media
|
422 | 425 | @RolesAllowed({ Role.USER, Role.ADMIN })
|
423 | 426 | @Path("/{itemname: [a-zA-Z_0-9]+}/state")
|
424 | 427 | @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( |
430 | 435 | @HeaderParam(HttpHeaders.ACCEPT_LANGUAGE) @Parameter(description = "language") @Nullable String language,
|
431 | 436 | @PathParam("itemname") @Parameter(description = "item name") String itemname,
|
432 | 437 | @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) { |
433 | 451 | final Locale locale = localeService.getLocale(language);
|
434 | 452 | final ZoneId zoneId = timeZoneProvider.getTimeZone();
|
435 | 453 |
|
@@ -459,12 +477,26 @@ public Response putItemState(
|
459 | 477 | @RolesAllowed({ Role.USER, Role.ADMIN })
|
460 | 478 | @Path("/{itemname: [a-zA-Z_0-9]+}")
|
461 | 479 | @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, |
467 | 487 | @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) { |
468 | 500 | Item item = getItem(itemname);
|
469 | 501 | Command command = null;
|
470 | 502 | if (item != null) {
|
@@ -1006,4 +1038,7 @@ private void addMetadata(EnrichedItemDTO dto, Set<String> namespaces, @Nullable
|
1006 | 1038 | private boolean isEditable(String itemName) {
|
1007 | 1039 | return managedItemProvider.get(itemName) != null;
|
1008 | 1040 | }
|
| 1041 | + |
| 1042 | + private record ValueContainer(String value) { |
| 1043 | + } |
1009 | 1044 | }
|
0 commit comments