/bundles/org.openhab.binding.tplinksmarthome/ @Hilbrand
/bundles/org.openhab.binding.tr064/ @openhab/add-ons-maintainers
/bundles/org.openhab.binding.tradfri/ @cweitkamp @kaikreuzer
+/bundles/org.openhab.binding.twitter/ @computergeek1507
/bundles/org.openhab.binding.unifi/ @mgbowman
/bundles/org.openhab.binding.unifiedremote/ @GiviMAD
/bundles/org.openhab.binding.upb/ @marcusb
--- /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
+
+== Third-party Content
+
+twitter4j
+* License: Apache License 2.0
+* Project: https://twitter4j.org/
+* Source: https://github.com/Twitter4J/Twitter4J
+
+
--- /dev/null
+# Twitter Binding
+
+The Twitter binding allows your home to Tweet 280 characters at a time. It also supports direct messages and tweeting with media.
+
+## Supported Things
+
+```
+account - Twitter Account.
+
+```
+
+## Thing Configuration
+
+The Twitter Account Thing requires you to create a Twitter App in the Twitter Developer Page.
+
+| Property | Default | Required | Description |
+|-------------------|---------|:--------:|-----------------------------------|
+| consumerKey | | Yes | Consumer API Key |
+| consumerSecret | | Yes | Consumer API Secret |
+| accessToken | | Yes | Access Token |
+| accessTokenSecret | | Yes | Access Token Secret |
+| refresh | 30 | No | Tweet refresh interval in minutes |
+
+
+## Channels
+
+| channel | type | description |
+|------------|--------|------------------------------------------------|
+| lasttweet | String | This channel provides the Latest Tweet message |
+
+
+## Full Example
+
+twitter.things:
+
+```
+Thing twitter:account:sampleaccount [ consumerKey="11111", consumerSecret="22222", accessToken="33333", accessTokenSecret="444444" ]
+
+```
+
+twitter.items:
+
+```
+String sample_tweet "Latest Tweet: [%s]" { channel="twitter:account:sampleaccount:lasttweet" }
+
+```
+
+## Rule Action
+
+This binding includes rule actions for sending tweets and direct messages.
+
+* `boolean success = sendTweet(String text)`
+* `boolean success = sendTweetWithAttachment(String text, String URL)`
+* `boolean success = sendDirectMessage(String recipientID, String text)`
+
+Examples:
+
+```
+val tweetActions = getActions("twitter","twitter:account:sampleaccount")
+val success = tweetActions.sendTweet("This is A Tweet")
+val success2 = tweetActions.sendTweetWithAttachment("This is A Tweet with a Pic", file:///tmp/201601011031.jpg)
+val success3 = tweetActions.sendTweetWithAttachment("Windows Picture", "D:\\Test.png" )
+val success4 = tweetActions.sendTweetWithAttachment("HTTP Picture", "http://www.mywebsite.com/Test.png" )
+val success5 = tweetActions.sendDirectMessage("1234567", "Wake Up" )
+
+```
--- /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 http://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>3.2.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>org.openhab.binding.twitter</artifactId>
+
+ <name>openHAB Add-ons :: Bundles :: Twitter Binding</name>
+
+ <properties>
+ <bnd.importpackage>!android.*,!com.android.org.*,!dalvik.*,!javax.annotation.meta.*,!org.apache.harmony.*,!org.conscrypt.*,!sun.*,!com.google.appengine.api.*</bnd.importpackage>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.twitter4j</groupId>
+ <artifactId>twitter4j-core</artifactId>
+ <version>4.0.7</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<features name="org.openhab.binding.twitter-${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-twitter" description="Twitter Binding" version="${project.version}">
+ <feature>openhab-runtime-base</feature>
+ <bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.twitter/${project.version}</bundle>
+ </feature>
+</features>
--- /dev/null
+/**
+ * Copyright (c) 2010-2021 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.twitter.internal;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.core.thing.ThingTypeUID;
+
+/**
+ * The {@link TwitterBindingConstants} class defines common constants, which are
+ * used across the whole binding.
+ *
+ * @author Scott Hanson - Initial contribution
+ */
+@NonNullByDefault
+public class TwitterBindingConstants {
+
+ private static final String BINDING_ID = "twitter";
+
+ // 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_LASTTWEET = "lasttweet";
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2021 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.twitter.internal;
+
+import static org.openhab.binding.twitter.internal.TwitterBindingConstants.CHANNEL_LASTTWEET;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.twitter.internal.action.TwitterActions;
+import org.openhab.binding.twitter.internal.config.TwitterConfig;
+import org.openhab.core.io.net.http.HttpUtil;
+import org.openhab.core.library.types.RawType;
+import org.openhab.core.library.types.StringType;
+import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.binding.BaseThingHandler;
+import org.openhab.core.thing.binding.ThingHandlerService;
+import org.openhab.core.types.Command;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import twitter4j.DirectMessage;
+import twitter4j.ResponseList;
+import twitter4j.Status;
+import twitter4j.StatusUpdate;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+import twitter4j.TwitterFactory;
+import twitter4j.auth.AccessToken;
+
+/**
+ * The {@link TwitterHandler} is responsible for handling commands, which are
+ * sent to one of the channels.
+ *
+ * @author Scott Hanson - Initial contribution
+ */
+
+@NonNullByDefault
+public class TwitterHandler extends BaseThingHandler {
+
+ private final Logger logger = LoggerFactory.getLogger(TwitterHandler.class);
+
+ private TwitterConfig config = new TwitterConfig();
+
+ private @Nullable ScheduledFuture<?> refreshTask;
+
+ private static final int CHARACTER_LIMIT = 280;
+
+ private static @Nullable Twitter client = null;
+ boolean isProperlyConfigured = false;
+
+ public TwitterHandler(Thing thing) {
+ super(thing);
+ }
+
+ @Override
+ public void handleCommand(ChannelUID channelUID, Command command) {
+ }
+
+ // creates list of available Actions
+ @Override
+ public Collection<Class<? extends ThingHandlerService>> getServices() {
+ return Collections.singletonList(TwitterActions.class);
+ }
+
+ @Override
+ public void initialize() {
+ config = getConfigAs(TwitterConfig.class);
+
+ // create a New Twitter Client
+ Twitter localClient = createClient();
+ client = localClient;
+ refresh();// Get latest status
+ isProperlyConfigured = true;
+ refreshTask = scheduler.scheduleWithFixedDelay(this::refresh, 0, config.refresh, TimeUnit.MINUTES);
+ updateStatus(ThingStatus.ONLINE);
+ }
+
+ @Override
+ public void dispose() {
+ ScheduledFuture<?> localRefreshTask = refreshTask;
+ if (localRefreshTask != null) {
+ localRefreshTask.cancel(true);
+ }
+ }
+
+ /**
+ * Internal method for Getting Twitter Status
+ *
+ */
+ private void refresh() {
+ try {
+ if (!checkPrerequisites()) {
+ return;
+ }
+ Twitter localClient = client;
+ if (localClient != null) {
+ ResponseList<Status> statuses = localClient.getUserTimeline();
+ if (statuses.size() > 0) {
+ updateState(CHANNEL_LASTTWEET, StringType.valueOf(statuses.get(0).getText()));
+ } else {
+ logger.debug("No Statuses Found");
+ }
+ }
+ } catch (TwitterException e) {
+ logger.debug("Error when trying to refresh Twitter Account: {}", e.getMessage());
+ }
+ }
+
+ /**
+ * Internal method for sending a tweet, with or without image
+ *
+ * @param tweetTxt
+ * text string to be sent as a Tweet
+ * @param fileToAttach
+ * the file to attach. May be null if no attached file.
+ *
+ * @return <code>true</code>, if sending the tweet has been successful and
+ * <code>false</code> in all other cases.
+ */
+ private boolean sendTweet(final String tweetTxt, final @Nullable File fileToAttach) {
+ if (!checkPrerequisites()) {
+ return false;
+ }
+ // abbreviate the Tweet to meet the 280 character limit ...
+ String abbreviatedTweetTxt = abbreviateString(tweetTxt, CHARACTER_LIMIT);
+ try {
+ Twitter localClient = client;
+ if (localClient != null) {
+ // send the Tweet
+ StatusUpdate status = new StatusUpdate(abbreviatedTweetTxt);
+ if (fileToAttach != null && fileToAttach.isFile()) {
+ status.setMedia(fileToAttach);
+ }
+ Status updatedStatus = localClient.updateStatus(status);
+ logger.debug("Successfully sent Tweet '{}'", updatedStatus.getText());
+ updateState(CHANNEL_LASTTWEET, StringType.valueOf(updatedStatus.getText()));
+ return true;
+ }
+ } catch (TwitterException e) {
+ logger.warn("Failed to send Tweet '{}' because of : {}", abbreviatedTweetTxt, e.getLocalizedMessage());
+ }
+ return false;
+ }
+
+ /**
+ * Sends a standard Tweet.
+ *
+ * @param tweetTxt
+ * text string to be sent as a Tweet
+ *
+ * @return <code>true</code>, if sending the tweet has been successful and
+ * <code>false</code> in all other cases.
+ */
+ public boolean sendTweet(String tweetTxt) {
+ if (!checkPrerequisites()) {
+ return false;
+ }
+ return sendTweet(tweetTxt, (File) null);
+ }
+
+ /**
+ * Sends a Tweet with an image
+ *
+ * @param tweetTxt
+ * text string to be sent as a Tweet
+ * @param tweetPicture
+ * the path of the picture that needs to be attached (either an url,
+ * either a path pointing to a local file)
+ *
+ * @return <code>true</code>, if sending the tweet has been successful and
+ * <code>false</code> in all other cases.
+ */
+ public boolean sendTweet(String tweetTxt, String tweetPicture) {
+ if (!checkPrerequisites()) {
+ return false;
+ }
+
+ // prepare the image attachment
+ File fileToAttach = null;
+ boolean deleteTemporaryFile = false;
+ if (tweetPicture.startsWith("http://") || tweetPicture.startsWith("https://")) {
+ try {
+ // we have a remote url and need to download the remote file to a temporary location
+ Path tDir = Files.createTempDirectory("TempDirectory");
+ String path = tDir + File.separator + "openhab-twitter-remote_attached_file" + "."
+ + getExtension(tweetPicture);
+
+ // URL url = new URL(tweetPicture);
+ fileToAttach = new File(path);
+ deleteTemporaryFile = true;
+
+ RawType rawPicture = HttpUtil.downloadImage(tweetPicture);
+ if (rawPicture != null) {
+ try (FileOutputStream fos = new FileOutputStream(path)) {
+ fos.write(rawPicture.getBytes(), 0, rawPicture.getBytes().length);
+ } catch (FileNotFoundException ex) {
+ logger.debug("Could not create {} in temp dir. {}", path, ex.getMessage());
+ } catch (IOException ex) {
+ logger.debug("Could not write {} to temp dir. {}", path, ex.getMessage());
+ }
+ } else {
+ logger.debug("Could not download tweet file from {}", tweetPicture);
+ }
+ } catch (IOException ex) {
+ logger.debug("Could not write {} to temp dir. {}", tweetPicture, ex.getMessage());
+ }
+ } else {
+ // we have a local file and can just use it directly
+ fileToAttach = new File(tweetPicture);
+ }
+
+ if (fileToAttach != null && fileToAttach.isFile()) {
+ logger.debug("Image '{}' correctly found, will be included in tweet", tweetPicture);
+ } else {
+ logger.warn("Image '{}' not found, will only tweet text", tweetPicture);
+ }
+
+ // send the Tweet
+ boolean result = sendTweet(tweetTxt, fileToAttach);
+ // delete temp file (if needed)
+ if (deleteTemporaryFile) {
+ if (fileToAttach != null) {
+ try {
+ fileToAttach.delete();
+ } catch (final Exception ignored) {
+ return false;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Sends a DirectMessage
+ *
+ * @param recipientId
+ * recipient ID of the twitter user
+ * @param messageTxt
+ * text string to be sent as a Direct Message
+ *
+ * @return <code>true</code>, if sending the direct message has been successful and
+ * <code>false</code> in all other cases.
+ */
+ public boolean sendDirectMessage(String recipientId, String messageTxt) {
+ if (!checkPrerequisites()) {
+ return false;
+ }
+
+ try {
+ Twitter localClient = client;
+ if (localClient != null) {
+ // abbreviate the Tweet to meet the allowed character limit ...
+ String abbreviatedMessageTxt = abbreviateString(messageTxt, CHARACTER_LIMIT);
+ // send the direct message
+ DirectMessage message = localClient.sendDirectMessage(recipientId, abbreviatedMessageTxt);
+ logger.debug("Successfully sent direct message '{}' to @'{}'", message.getText(),
+ message.getRecipientId());
+ return true;
+ }
+ } catch (TwitterException e) {
+ logger.warn("Failed to send Direct Message '{}' because of :'{}'", messageTxt, e.getLocalizedMessage());
+ }
+ return false;
+ }
+
+ /**
+ * check if twitter account was created with prerequisites
+ *
+ * @return <code>true</code>, if twitter account was initialized
+ * <code>false</code> in all other cases.
+ */
+ private boolean checkPrerequisites() {
+ if (client == null) {
+ logger.debug("Twitter client is not yet configured > execution aborted!");
+ return false;
+ }
+ if (!isProperlyConfigured) {
+ logger.debug("Twitter client is not yet configured > execution aborted!");
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Creates and returns a Twitter4J Twitter client.
+ *
+ * @return a new instance of a Twitter4J Twitter client.
+ */
+ private twitter4j.Twitter createClient() {
+ twitter4j.Twitter client = TwitterFactory.getSingleton();
+ client.setOAuthConsumer(config.consumerKey, config.consumerSecret);
+ client.setOAuthAccessToken(new AccessToken(config.accessToken, config.accessTokenSecret));
+ return client;
+ }
+
+ public static String abbreviateString(String input, int maxLength) {
+ if (input.length() <= maxLength) {
+ return input;
+ } else {
+ return input.substring(0, maxLength);
+ }
+ }
+
+ public static String getExtension(String filename) {
+ if (filename.contains(".")) {
+ return filename.substring(filename.lastIndexOf(".") + 1);
+ }
+ return new String();
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2021 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.twitter.internal;
+
+import static org.openhab.binding.twitter.internal.TwitterBindingConstants.THING_TYPE_ACCOUNT;
+
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+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.Component;
+
+/**
+ * The {@link TwitterHandlerFactory} is responsible for creating things and thing
+ * handlers.
+ *
+ * @author Scott Hanson - Initial contribution
+ */
+@NonNullByDefault
+@Component(configurationPid = "binding.twitter", service = ThingHandlerFactory.class)
+public class TwitterHandlerFactory extends BaseThingHandlerFactory {
+
+ private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_ACCOUNT);
+
+ @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 TwitterHandler(thing);
+ }
+
+ return null;
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2021 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.twitter.internal.action;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.twitter.internal.TwitterHandler;
+import org.openhab.core.automation.annotation.ActionInput;
+import org.openhab.core.automation.annotation.ActionOutput;
+import org.openhab.core.automation.annotation.RuleAction;
+import org.openhab.core.thing.binding.ThingActions;
+import org.openhab.core.thing.binding.ThingActionsScope;
+import org.openhab.core.thing.binding.ThingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link TweetActions} class defines rule actions for sending tweet
+ *
+ * @author Scott Hanson - Initial contribution
+ */
+@ThingActionsScope(name = "twitter")
+@NonNullByDefault
+public class TwitterActions implements ThingActions {
+
+ private final Logger logger = LoggerFactory.getLogger(TwitterActions.class);
+
+ private @Nullable TwitterHandler handler;
+
+ @RuleAction(label = "@text/sendTweetActionLabel", description = "@text/sendTweetActionDescription")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendTweet(
+ @ActionInput(name = "text") @Nullable String text) {
+ if (text == null) {
+ logger.warn("Cannot send Tweet as text is missing.");
+ return false;
+ }
+
+ final TwitterHandler handler = this.handler;
+ if (handler == null) {
+ logger.debug("Handler is null, cannot tweet.");
+ return false;
+ } else {
+ return handler.sendTweet(text);
+ }
+ }
+
+ @RuleAction(label = "@text/sendAttachmentTweetActionLabel", description = "@text/sendAttachmentTweetActionDescription")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendTweetWithAttachment(
+ @ActionInput(name = "text") @Nullable String text, @ActionInput(name = "url") @Nullable String urlString) {
+ if (text == null) {
+ logger.warn("Cannot send Tweet as text is missing.");
+ return false;
+ }
+ if (urlString == null) {
+ logger.warn("Cannot send Tweet as urlString is missing.");
+ return false;
+ }
+
+ final TwitterHandler handler = this.handler;
+ if (handler == null) {
+ logger.debug("Handler is null, cannot tweet.");
+ return false;
+ } else {
+ return handler.sendTweet(text, urlString);
+ }
+ }
+
+ @RuleAction(label = "@text/sendDirectMessageActionLabel", description = "@text/sendDirectMessageActionDescription")
+ public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendDirectMessage(
+ @ActionInput(name = "recipient") @Nullable String recipient,
+ @ActionInput(name = "text") @Nullable String text) {
+ if (recipient == null) {
+ logger.warn("Cannot send Direct Message as recipient is missing.");
+ return false;
+ }
+ if (text == null) {
+ logger.warn("Cannot send Direct Message as text is missing.");
+ return false;
+ }
+
+ final TwitterHandler handler = this.handler;
+ if (handler == null) {
+ logger.debug("Handler is null, cannot tweet.");
+ return false;
+ } else {
+ return handler.sendDirectMessage(recipient, text);
+ }
+ }
+
+ public static boolean sendTweet(ThingActions actions, @Nullable String text) {
+ return ((TwitterActions) actions).sendTweet(text);
+ }
+
+ public static boolean sendTweetWithAttachment(ThingActions actions, @Nullable String text,
+ @Nullable String urlString) {
+ return ((TwitterActions) actions).sendTweetWithAttachment(text, urlString);
+ }
+
+ public static boolean sendDirectMessage(ThingActions actions, @Nullable String recipient, @Nullable String text) {
+ return ((TwitterActions) actions).sendDirectMessage(recipient, text);
+ }
+
+ @Override
+ public void setThingHandler(@Nullable ThingHandler handler) {
+ if (handler instanceof TwitterHandler) {
+ this.handler = (TwitterHandler) handler;
+ }
+ }
+
+ @Override
+ public @Nullable ThingHandler getThingHandler() {
+ return handler;
+ }
+}
--- /dev/null
+/**
+ * Copyright (c) 2010-2021 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.twitter.internal.config;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link TwitterConfig} class contains fields mapping thing configuration parameters.
+ *
+ * @author Scott Hanson - Initial contribution
+ */
+
+@NonNullByDefault
+public class TwitterConfig {
+ public String consumerKey = "";
+ public String consumerSecret = "";
+ public String accessToken = "";
+ public String accessTokenSecret = "";
+ public int refresh = 30;
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<binding:binding id="twitter" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
+ xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
+
+ <name>Twitter Binding</name>
+ <description>Supports adding Thing for getting the Last Tweet. Send Tweets and Pictures with Actions.</description>
+
+</binding:binding>
--- /dev/null
+# actions
+sendTweetActionLabel = send a Tweet
+sendTweetActionDescription = Sends a Tweet.
+
+sendAttachmentTweetActionLabel = send a Tweet with attachment
+sendAttachmentTweetActionDescription = Sends a Tweet with an attachment.
+
+sendDirectMessageActionLabel = send a DirectMessage
+sendDirectMessageActionDescription = Sends a DirectMessage.
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="twitter"
+ 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">
+ <label>Twitter Account</label>
+ <description>Account uses for sending Tweets</description>
+
+ <channels>
+ <channel id="lasttweet" typeId="lasttweet"/>
+ </channels>
+
+ <config-description>
+ <parameter name="consumerKey" type="text" required="true">
+ <label>Consumer API Key</label>
+ <context>password</context>
+ </parameter>
+ <parameter name="consumerSecret" type="text" required="true">
+ <label>Consumer API Secret</label>
+ <context>password</context>
+ </parameter>
+ <parameter name="accessToken" type="text" required="true">
+ <label>Access Token</label>
+ <context>password</context>
+ </parameter>
+ <parameter name="accessTokenSecret" type="text" required="true">
+ <label>Access Token Secret</label>
+ <context>password</context>
+ </parameter>
+ <parameter name="refresh" type="integer" required="false" unit="min" min="1">
+ <label>Refresh Time</label>
+ <description>Refresh Time for This Account in Mins</description>
+ <default>30</default>
+ </parameter>
+ </config-description>
+
+ </thing-type>
+
+ <channel-type id="lasttweet">
+ <item-type>String</item-type>
+ <label>Last Tweet</label>
+ <description>Users Last Tweet</description>
+ <state readOnly="true"/>
+ </channel-type>
+</thing:thing-descriptions>
<module>org.openhab.binding.tplinksmarthome</module>
<module>org.openhab.binding.tr064</module>
<module>org.openhab.binding.tradfri</module>
+ <module>org.openhab.binding.twitter</module>
<module>org.openhab.binding.unifi</module>
<module>org.openhab.binding.unifiedremote</module>
<module>org.openhab.binding.upnpcontrol</module>