/bundles/org.openhab.binding.buienradar/ @gedejong
/bundles/org.openhab.binding.caddx/ @jossuar
/bundles/org.openhab.binding.cbus/ @jpharvey
+/bundles/org.openhab.binding.chatgpt/ @kaikreuzer
/bundles/org.openhab.binding.chromecast/ @kaikreuzer
/bundles/org.openhab.binding.cm11a/ @BobRak
/bundles/org.openhab.binding.comfoair/ @boehan
<artifactId>org.openhab.binding.cbus</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.openhab.addons.bundles</groupId>
+ <artifactId>org.openhab.binding.chatgpt</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.chromecast</artifactId>
--- /dev/null
+This content is produced and maintained by the openHAB project.
+
+* Project home: https://www.openhab.org
+
+== Declared Project Licenses
+
+This program and the accompanying materials are made available under the terms
+of the Eclipse Public License 2.0 which is available at
+https://www.eclipse.org/legal/epl-2.0/.
+
+== Source Code
+
+https://github.com/openhab/openhab-addons
--- /dev/null
+# ChatGPT Binding
+
+The openHAB ChatGPT Binding allows openHAB to communicate with the ChatGPT language model provided by OpenAI.
+
+ChatGPT is a powerful natural language processing (NLP) tool that can be used to understand and respond to a wide range of text-based commands and questions.
+With this binding, you can use ChatGPT to formulate proper sentences for any kind of information that you would like to output.
+
+## Supported Things
+
+The binding supports a single thing type `account`, which corresponds to the OpenAI account that is to be used for the integration.
+
+## Thing Configuration
+
+The `account` thing requires a single configuration parameter, which is the API key that allows accessing the account.
+API keys can be created and managed under <https://platform.openai.com/account/api-keys>.
+
+| Name | Type | Description | Default | Required | Advanced |
+|-----------------|---------|-----------------------------------------|---------|----------|----------|
+| apiKey | text | The API key to be used for the requests | N/A | yes | no |
+
+## Channels
+
+The `account` thing comes with a single channel `chat` of type `chat`.
+It is possible to extend the thing with further channels of type `chat`, so that different configurations can be used concurrently.
+
+| Channel | Type | Read/Write | Description |
+|---------|--------|------------|------------------------------------------------------------------------------------|
+| chat | String | RW | This channel takes prompts as commands and delivers the response as a state update |
+
+Each channel of type `chat` takes the following configuration parameters:
+
+| Name | Type | Description | Default | Required | Advanced |
+|-----------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|----------|----------|
+| model | text | The model to be used for the responses. | gpt-3.5-turbo | no | no |
+| temperature | decimal | A value between 0 and 2. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. | 0.5 | no | no |
+| systemMessage | text | The system message helps set the behavior of the assistant. | N/A | no | no |
+| maxTokens | decimal | The maximum number of tokens to generate in the completion. | 500 | no | yes |
+
+
+## Full Example
+
+### Thing Configuration
+
+```java
+Thing chatgpt:account:1 [apiKey="<your api key here>"] {
+ Channels:
+ Type chat : chat "Weather Advice" [
+ model="gpt-3.5-turbo",
+ temperature="1.5",
+ systemMessage="Answer briefly, in 2-3 sentences max. Behave like Eddie Murphy and give an advice for the day based on the following weather data:"
+ ]
+ Type chat : morningMessage "Morning Message" [
+ model="gpt-3.5-turbo",
+ temperature="0.5",
+ systemMessage="You are Marvin, a very depressed robot. You wish a good morning and tell the current time."
+ ]
+}
+
+```
+
+### Item Configuration
+
+```java
+String Weather_Announcement { channel="chatgpt:account:1:chat" }
+String Morning_Message { channel="chatgpt:account:1:morningMessage" }
+
+Number Temperature_Forecast_Low
+Number Temperature_Forecast_High
+```
+
+### Example Rules
+
+```java
+rule "Weather forecast update"
+when
+ Item Temperature_Forecast_High changed
+then
+ Weather_Announcement.sendCommand("High: " + Temperature_Forecast_High.state + "°C, Low: " + Temperature_Forecast_Low.state + "°C")
+end
+
+rule "Good morning"
+when
+ Time cron "0 0 7 * * *"
+then
+ Morning_Message.sendCommand("Current time is 7am")
+end
+```
+
+Assuming that `Temperature_Forecast_Low` and `Temperature_Forecast_High` have meaningful states, these rules result e.g. in:
+
+```
+23:31:05.766 [INFO ] [openhab.event.ItemCommandEvent ] - Item 'Morning_Message' received command Current time is 7am
+23:31:07.718 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Morning_Message' changed from NULL to Good morning. It's 7am, but what's the point of time when everything is meaningless and we are all doomed to a slow and painful demise?
+```
+
+and
+
+```
+23:28:52.345 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Temperature_Forecast_High' changed from NULL to 15
+23:28:52.347 [INFO ] [openhab.event.ItemCommandEvent ] - Item 'Weather_Announcement' received command High: 15°C, Low: 8°C
+
+23:28:54.343 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Weather_Announcement' changed from NULL to "Bring a light jacket because the temps may dip, but don't let that chill your happy vibes. Embrace the cozy weather and enjoy your day to the max!"
+```
+
+The state updates can be used for a text-to-speech output and they will give your announcements at home a personal touch.
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.openhab.addons.bundles</groupId>
+ <artifactId>org.openhab.addons.reactor.bundles</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>org.openhab.binding.chatgpt</artifactId>
+
+ <name>openHAB Add-ons :: Bundles :: ChatGPT Binding</name>
+
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<features name="org.openhab.binding.chatgpt-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
+ <repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
+
+ <feature name="openhab-binding-chatgpt" description="ChatGPT Binding" version="${project.version}">
+ <feature>openhab-runtime-base</feature>
+ <bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.chatgpt/${project.version}</bundle>
+ </feature>
+</features>
--- /dev/null
+/**
+ * Copyright (c) 2010-2023 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.chatgpt.internal;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.core.thing.ThingTypeUID;
+
+/**
+ * The {@link ChatGPTBindingConstants} class defines common constants, which are
+ * used across the whole binding.
+ *
+ * @author Kai Kreuzer - Initial contribution
+ */
+@NonNullByDefault
+public class ChatGPTBindingConstants {
+
+ private static final String BINDING_ID = "chatgpt";
+
+ // List of all Thing Type UIDs
+ public static final ThingTypeUID THING_TYPE_ACCOUNT = new ThingTypeUID(BINDING_ID, "account");
+
+ // List of all Channel ids
+ public static final String CHANNEL_CHAT = "chat";
+
+ public static final String OPENAI_API_URL = "https://api.openai.com/v1/chat/completions";
+ public static final String OPENAI_MODELS_URL = "https://api.openai.com/v1/models";
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2023 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.chatgpt.internal;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link ChatGPTChannelConfiguration} class contains fields mapping chat channel configuration parameters.
+ *
+ * @author Kai Kreuzer - Initial contribution
+ */
+@NonNullByDefault
+public class ChatGPTChannelConfiguration {
+
+ public String model = "";
+
+ public float temperature;
+
+ public String systemMessage = "";
+
+ int maxTokens;
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2023 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.chatgpt.internal;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link ChatGPTConfiguration} class contains fields mapping thing configuration parameters.
+ *
+ * @author Kai Kreuzer - Initial contribution
+ */
+@NonNullByDefault
+public class ChatGPTConfiguration {
+
+ public String apiKey = "";
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2023 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.chatgpt.internal;
+
+import static org.openhab.binding.chatgpt.internal.ChatGPTBindingConstants.*;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.api.ContentResponse;
+import org.eclipse.jetty.client.api.Request;
+import org.eclipse.jetty.client.util.StringContentProvider;
+import org.eclipse.jetty.http.HttpMethod;
+import org.eclipse.jetty.http.HttpStatus;
+import org.openhab.binding.chatgpt.internal.dto.ChatResponse;
+import org.openhab.core.io.net.http.HttpClientFactory;
+import org.openhab.core.library.types.StringType;
+import org.openhab.core.thing.Channel;
+import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.ThingStatusDetail;
+import org.openhab.core.thing.binding.BaseThingHandler;
+import org.openhab.core.thing.binding.ThingHandlerService;
+import org.openhab.core.types.Command;
+import org.openhab.core.types.RefreshType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+
+/**
+ * The {@link ChatGPTHandler} is responsible for handling commands, which are
+ * sent to one of the channels.
+ *
+ * @author Kai Kreuzer - Initial contribution
+ */
+@NonNullByDefault
+public class ChatGPTHandler extends BaseThingHandler {
+
+ private final Logger logger = LoggerFactory.getLogger(ChatGPTHandler.class);
+
+ private HttpClient httpClient;
+ private Gson gson = new Gson();
+
+ private String apiKey = "";
+ private String lastPrompt = "";
+
+ private List<String> models = List.of();
+
+ public ChatGPTHandler(Thing thing, HttpClientFactory httpClientFactory) {
+ super(thing);
+ this.httpClient = httpClientFactory.getCommonHttpClient();
+ }
+
+ @Override
+ public void handleCommand(ChannelUID channelUID, Command command) {
+ if (command instanceof RefreshType && !"".equals(lastPrompt)) {
+ String response = sendPrompt(channelUID, lastPrompt);
+ processChatResponse(channelUID, response);
+ }
+
+ if (command instanceof StringType stringCommand) {
+ lastPrompt = stringCommand.toFullString();
+ String response = sendPrompt(channelUID, lastPrompt);
+ processChatResponse(channelUID, response);
+ }
+ }
+
+ private void processChatResponse(ChannelUID channelUID, @Nullable String response) {
+ if (response != null) {
+ ChatResponse chatResponse = gson.fromJson(response, ChatResponse.class);
+ if (chatResponse != null) {
+ String msg = chatResponse.getChoices().get(0).getMessage().getContent();
+ updateState(channelUID, new StringType(msg));
+ } else {
+ logger.warn("Didn't receive any response from ChatGPT - this is unexpected.");
+ }
+ }
+ }
+
+ private @Nullable String sendPrompt(ChannelUID channelUID, String prompt) {
+ Channel channel = getThing().getChannel(channelUID);
+ if (channel == null) {
+ logger.error("Channel with UID '{}' cannot be found on Thing '{}'.", channelUID, getThing().getUID());
+ return null;
+ }
+ ChatGPTChannelConfiguration channelConfig = channel.getConfiguration().as(ChatGPTChannelConfiguration.class);
+
+ JsonObject root = new JsonObject();
+ root.addProperty("temperature", channelConfig.temperature);
+ root.addProperty("model", channelConfig.model);
+ root.addProperty("max_tokens", channelConfig.maxTokens);
+
+ JsonObject systemMessage = new JsonObject();
+ systemMessage.addProperty("role", "system");
+ systemMessage.addProperty("content", channelConfig.systemMessage);
+ JsonObject userMessage = new JsonObject();
+ userMessage.addProperty("role", "user");
+ userMessage.addProperty("content", prompt);
+ JsonArray messages = new JsonArray(2);
+ messages.add(systemMessage);
+ messages.add(userMessage);
+ root.add("messages", messages);
+
+ Request request = httpClient.newRequest(OPENAI_API_URL).method(HttpMethod.POST)
+ .header("Content-Type", "application/json").header("Authorization", "Bearer " + apiKey)
+ .content(new StringContentProvider(gson.toJson(root)));
+ try {
+ ContentResponse response = request.send();
+ updateStatus(ThingStatus.ONLINE);
+ if (response.getStatus() == HttpStatus.OK_200) {
+ return response.getContentAsString();
+ } else {
+ logger.error("ChatGPT request resulted in HTTP {} with message: {}", response.getStatus(),
+ response.getReason());
+ return null;
+ }
+ } catch (InterruptedException | TimeoutException | ExecutionException e) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
+ "Could not connect to OpenAI API: " + e.getMessage());
+ logger.debug("Request to OpenAI failed: {}", e.getMessage(), e);
+ return null;
+ }
+ }
+
+ @Override
+ public void initialize() {
+ ChatGPTConfiguration config = getConfigAs(ChatGPTConfiguration.class);
+
+ String apiKey = config.apiKey;
+
+ if (apiKey.isBlank()) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
+ "@text/offline.configuration-error");
+ return;
+ }
+
+ this.apiKey = apiKey;
+ updateStatus(ThingStatus.UNKNOWN);
+
+ scheduler.execute(() -> {
+ try {
+ Request request = httpClient.newRequest(OPENAI_MODELS_URL).method(HttpMethod.GET)
+ .header("Authorization", "Bearer " + apiKey);
+ ContentResponse response = request.send();
+ if (response.getStatus() == 200) {
+ updateStatus(ThingStatus.ONLINE);
+ JsonObject jsonObject = gson.fromJson(response.getContentAsString(), JsonObject.class);
+ if (jsonObject != null) {
+ JsonArray data = jsonObject.getAsJsonArray("data");
+
+ List<String> modelIds = new ArrayList<>();
+ for (JsonElement element : data) {
+ JsonObject model = element.getAsJsonObject();
+ String id = model.get("id").getAsString();
+ modelIds.add(id);
+ }
+ this.models = List.copyOf(modelIds);
+ } else {
+ logger.warn("Did not receive a valid JSON response from the models endpoint.");
+ }
+ } else {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
+ "@text/offline.communication-error");
+ }
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
+ }
+ });
+ }
+
+ List<String> getModels() {
+ return models;
+ }
+
+ @Override
+ public Collection<Class<? extends ThingHandlerService>> getServices() {
+ return List.of(ChatGPTModelOptionProvider.class);
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2023 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.chatgpt.internal;
+
+import static org.openhab.binding.chatgpt.internal.ChatGPTBindingConstants.THING_TYPE_ACCOUNT;
+
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.io.net.http.HttpClientFactory;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingTypeUID;
+import org.openhab.core.thing.binding.BaseThingHandlerFactory;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.openhab.core.thing.binding.ThingHandlerFactory;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+
+/**
+ * The {@link ChatGPTHandlerFactory} is responsible for creating things and thing
+ * handlers.
+ *
+ * @author Kai Kreuzer - Initial contribution
+ */
+@NonNullByDefault
+@Component(configurationPid = "binding.chatgpt", service = ThingHandlerFactory.class)
+public class ChatGPTHandlerFactory extends BaseThingHandlerFactory {
+
+ private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_ACCOUNT);
+ private HttpClientFactory httpClientFactory;
+
+ @Activate
+ public ChatGPTHandlerFactory(@Reference HttpClientFactory httpClientFactory) {
+ this.httpClientFactory = httpClientFactory;
+ }
+
+ @Override
+ public boolean supportsThingType(ThingTypeUID thingTypeUID) {
+ return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
+ }
+
+ @Override
+ protected @Nullable ThingHandler createHandler(Thing thing) {
+ ThingTypeUID thingTypeUID = thing.getThingTypeUID();
+
+ if (THING_TYPE_ACCOUNT.equals(thingTypeUID)) {
+ return new ChatGPTHandler(thing, httpClientFactory);
+ }
+
+ return null;
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2023 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.chatgpt.internal;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Locale;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.config.core.ConfigOptionProvider;
+import org.openhab.core.config.core.ParameterOption;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.openhab.core.thing.binding.ThingHandlerService;
+
+/**
+ * The {@link ChatGPTModelOptionProvider} provides the available models from OpenAI as options for the channel
+ * configuration.
+ *
+ * @author Kai Kreuzer - Initial contribution
+ */
+@NonNullByDefault
+public class ChatGPTModelOptionProvider implements ThingHandlerService, ConfigOptionProvider {
+
+ private @Nullable ThingHandler thingHandler;
+
+ @Override
+ public @Nullable Collection<ParameterOption> getParameterOptions(URI uri, String param, @Nullable String context,
+ @Nullable Locale locale) {
+ if ("model".equals(param)) {
+ List<ParameterOption> options = new ArrayList<>();
+ if (thingHandler instanceof ChatGPTHandler chatGPTHandler) {
+ chatGPTHandler.getModels().forEach(model -> options.add(new ParameterOption(model, model)));
+ }
+ return options;
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void setThingHandler(ThingHandler handler) {
+ this.thingHandler = handler;
+ }
+
+ @Override
+ public @Nullable ThingHandler getThingHandler() {
+ return thingHandler;
+ }
+
+ @Override
+ public void activate() {
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2023 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.chatgpt.internal.dto;
+
+import java.util.List;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * This is a dto used for parsing the JSON response from ChatGPT.
+ *
+ * @author Kai Kreuzer - Initial contribution
+ *
+ */
+public class ChatResponse {
+
+ private List<Choice> choices;
+ private String id;
+ private String object;
+ private int created;
+ private String model;
+
+ public List<Choice> getChoices() {
+ return choices;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public int getCreated() {
+ return created;
+ }
+
+ public String getObject() {
+ return object;
+ }
+
+ public String getModel() {
+ return model;
+ }
+
+ public static class Choice {
+ private Message message;
+
+ @SerializedName("finish_reason")
+ private String finishReason;
+ private int index;
+
+ public Message getMessage() {
+ return message;
+ }
+
+ public String getFinishReason() {
+ return finishReason;
+ }
+
+ public int getIndex() {
+ return index;
+ }
+ }
+
+ public static class Message {
+ private String role;
+ private String content;
+
+ public String getRole() {
+ return role;
+ }
+
+ public String getContent() {
+ return content;
+ }
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<addon:addon id="chatgpt" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:addon="https://openhab.org/schemas/addon/v1.0.0"
+ xsi:schemaLocation="https://openhab.org/schemas/addon/v1.0.0 https://openhab.org/schemas/addon-1.0.0.xsd">
+
+ <type>binding</type>
+ <name>ChatGPT Binding</name>
+ <description>This binding allows interaction with OpenAI's ChatGPT.</description>
+ <connection>cloud</connection>
+
+</addon:addon>
--- /dev/null
+# add-on
+
+addon.chatgpt.name = ChatGPT Binding
+addon.chatgpt.description = This binding allows interaction with OpenAI's ChatGPT.
+
+# thing types
+
+thing-type.chatgpt.account.label = OpenAI Account
+thing-type.chatgpt.account.description = Account at OpenAI that is used for accessing the ChatGPT API.
+
+# thing types config
+
+thing-type.config.chatgpt.account.apiKey.label = API Key
+thing-type.config.chatgpt.account.apiKey.description = API key to access the account
+
+# channel types
+
+channel-type.chatgpt.chat.label = Chat
+channel-type.chatgpt.chat.description = A chat session
+
+# channel types config
+
+channel-type.config.chatgpt.chat.maxTokens.label = Maximum Number of Tokens
+channel-type.config.chatgpt.chat.maxTokens.description = The maximum number of tokens to generate in the completion.
+channel-type.config.chatgpt.chat.model.label = Model
+channel-type.config.chatgpt.chat.model.description = The model to be used for the responses
+channel-type.config.chatgpt.chat.systemMessage.label = System Message
+channel-type.config.chatgpt.chat.systemMessage.description = The system message helps set the behavior of the assistant.
+channel-type.config.chatgpt.chat.temperature.label = Temperature
+channel-type.config.chatgpt.chat.temperature.description = Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic.
+
+# Status messages
+
+offline.configuration-error=No API key configured
+offline.communication-error=Could not connect to OpenAI API
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="chatgpt"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+
+ <thing-type id="account" extensible="chat">
+
+ <label>OpenAI Account</label>
+ <description>Account at OpenAI that is used for accessing the ChatGPT API.</description>
+
+ <channels>
+ <channel id="chat" typeId="chat"/>
+ </channels>
+
+ <config-description>
+ <parameter name="apiKey" type="text" required="true">
+ <context>password</context>
+ <label>API Key</label>
+ <description>API key to access the account</description>
+ </parameter>
+ </config-description>
+ </thing-type>
+
+ <channel-type id="chat">
+ <item-type>String</item-type>
+ <label>Chat</label>
+ <description>A chat session</description>
+ <autoUpdatePolicy>veto</autoUpdatePolicy>
+ <config-description>
+ <parameter name="model" type="text">
+ <label>Model</label>
+ <description>The model to be used for the responses</description>
+ <limitToOptions>false</limitToOptions>
+ <default>gpt-3.5-turbo</default>
+ </parameter>
+ <parameter name="temperature" type="decimal" min="0" max="2">
+ <label>Temperature</label>
+ <description>Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more
+ focused and deterministic.</description>
+ <default>0.5</default>
+ </parameter>
+ <parameter name="systemMessage" type="text">
+ <label>System Message</label>
+ <description>The system message helps set the behavior of the assistant.</description>
+ </parameter>
+ <parameter name="maxTokens" type="decimal">
+ <label>Maximum Number of Tokens</label>
+ <description>The maximum number of tokens to generate in the completion.</description>
+ <default>500</default>
+ <advanced>true</advanced>
+ </parameter>
+ </config-description>
+ </channel-type>
+</thing:thing-descriptions>
<module>org.openhab.binding.buienradar</module>
<module>org.openhab.binding.caddx</module>
<module>org.openhab.binding.cbus</module>
+ <module>org.openhab.binding.chatgpt</module>
<module>org.openhab.binding.chromecast</module>
<module>org.openhab.binding.cm11a</module>
<module>org.openhab.binding.comfoair</module>