From 958388d6c562c0b7cde7ff7032fb00cbc2d4fc90 Mon Sep 17 00:00:00 2001 From: Kiril Atanasov Date: Wed, 2 Nov 2016 11:37:08 +0200 Subject: [PATCH] Add coding tasks for OSGi, III. Service Tracker (#113) Sample implementations of the [third part of the OSGi Coding Tasks](http://docs.openhab.org/developers/prerequisites/osgitasks.html#iii-service-tracker). Modified org.openhab.training.electricity.provider bundle. Also-by: Elena Miovska (github: emiovska) Signed-off-by: Kiril Atanasov (github: kirilAtan) --- .../.classpath | 7 + .../.project | 28 ++ .../META-INF/MANIFEST.MF | 13 + .../about.html | 28 ++ .../build.properties | 4 + .../training/electricity/battery/Battery.java | 48 +++ .../electricity/battery/BatteryActivator.java | 36 +++ .../.classpath | 7 + .../.project | 28 ++ .../META-INF/MANIFEST.MF | 11 + .../about.html | 28 ++ .../build.properties | 4 + .../dynamicconsumer/DynamicConsumer.java | 38 +++ .../about.html | 7 +- .../provider/ElectricityProvider.java | 12 +- .../provider/ElectricityProviderType.java | 20 ++ .../.classpath | 7 + .../.project | 28 ++ .../META-INF/MANIFEST.MF | 17 ++ .../TVRuntimeEvnironment.launch | 26 ++ .../about.html | 28 ++ .../build.properties | 4 + .../openhab/training/electricity/tv/TV.java | 281 ++++++++++++++++++ .../training/electricity/tv/TVActivator.java | 69 +++++ .../tv/TvPowerProviderTracker.java | 84 ++++++ 25 files changed, 857 insertions(+), 6 deletions(-) create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/.classpath create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/.project create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/META-INF/MANIFEST.MF create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/about.html create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/build.properties create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/src/main/java/org/openhab/training/electricity/battery/Battery.java create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/src/main/java/org/openhab/training/electricity/battery/BatteryActivator.java create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/.classpath create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/.project create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/META-INF/MANIFEST.MF create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/about.html create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/build.properties create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/src/main/java/org/openhab/training/electricity/dynamicconsumer/DynamicConsumer.java create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.provider/src/main/java/org/openhab/training/electricity/provider/ElectricityProviderType.java create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/.classpath create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/.project create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/META-INF/MANIFEST.MF create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/TVRuntimeEvnironment.launch create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/about.html create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/build.properties create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/src/main/java/org/openhab/training/electricity/tv/TV.java create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/src/main/java/org/openhab/training/electricity/tv/TVActivator.java create mode 100644 _sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/src/main/java/org/openhab/training/electricity/tv/TvPowerProviderTracker.java diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/.classpath b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/.classpath new file mode 100644 index 000000000..a95e0906c --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/.project b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/.project new file mode 100644 index 000000000..2f66c41d1 --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/.project @@ -0,0 +1,28 @@ + + + org.openhab.training.electricity.battery + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/META-INF/MANIFEST.MF b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/META-INF/MANIFEST.MF new file mode 100644 index 000000000..aeb7b1eef --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/META-INF/MANIFEST.MF @@ -0,0 +1,13 @@ +Manifest-Version: 1.0 +Bundle-Name: Battery +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-Vendor: openHAB.org +Bundle-Version: 1.0.0.qualifier +Bundle-ManifestVersion: 2 +Bundle-License: http://www.eclipse.org/legal/epl-v10.html +Bundle-SymbolicName: org.openhab.training.electricity.battery +Import-Package: org.openhab.training.electricity.battery, + org.openhab.training.electricity.provider, + org.osgi.framework +Export-Package: org.openhab.training.electricity.battery +Bundle-Activator: org.openhab.training.electricity.battery.BatteryActivator diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/about.html b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/about.html new file mode 100644 index 000000000..9db40b3c9 --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/about.html @@ -0,0 +1,28 @@ + + + + +About + + +

About This Content

+ +

<September 15, 2014>

+

License

+ +

The openHAB community makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

+ +

If you did not receive this Content directly from the openHAB community, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at openhab.org.

+ + + diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/build.properties b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/build.properties new file mode 100644 index 000000000..ba87267c7 --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/build.properties @@ -0,0 +1,4 @@ +source.. = src/main/java +output.. = target/classes/ +bin.includes = META-INF/,\ + . diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/src/main/java/org/openhab/training/electricity/battery/Battery.java b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/src/main/java/org/openhab/training/electricity/battery/Battery.java new file mode 100644 index 000000000..539823ecc --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/src/main/java/org/openhab/training/electricity/battery/Battery.java @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2014-2016 by the respective copyright holders. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.openhab.training.electricity.battery; + +import org.openhab.training.electricity.provider.ElectricityProvider; +import org.openhab.training.electricity.provider.ElectricityProviderType; + +/** + * The class {@link Battery} is an {@link ElectricityProvider} which has a + * limited amount of energy it can provide. + * + * @author Kiril Atanasov - Initial contribution + */ +public class Battery implements ElectricityProvider { + + /** The amount of energy the Battery can provide */ + protected int energyAmount = 20; + + /** + * Checks if the {@link Battery} has enough energy to power a consumer, + * based on its consumption. The method is synchronized in case there are + * multiple consumers using the {@link Battery} service at the same time. + * + * @param value + * the amount of energy that is being demanded. + * @return true if the {@link Battery} can provide the demanded amount of + * energy, false otherwise. + */ + @Override + public synchronized boolean provide(int value) { + if (value >= 0 && value <= energyAmount) { + energyAmount -= value; + return true; + } + return false; + } + + @Override + public ElectricityProviderType getType() { + return ElectricityProviderType.BATTERY; + } +} diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/src/main/java/org/openhab/training/electricity/battery/BatteryActivator.java b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/src/main/java/org/openhab/training/electricity/battery/BatteryActivator.java new file mode 100644 index 000000000..e549c84f4 --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.battery/src/main/java/org/openhab/training/electricity/battery/BatteryActivator.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2014-2016 by the respective copyright holders. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.openhab.training.electricity.battery; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; +import org.openhab.training.electricity.provider.ElectricityProvider; + +/** + * The class {@link BatteryActivator} activates this bundle. + * + * @author Kiril Atanasov - Initial contribution + */ +public class BatteryActivator implements BundleActivator { + + private ServiceRegistration batteryServiceRegistration; + + @SuppressWarnings("unchecked") + @Override + public void start(BundleContext context) throws Exception { + batteryServiceRegistration = (ServiceRegistration) context + .registerService(ElectricityProvider.class.getName(), new Battery(), null); + } + + @Override + public void stop(BundleContext context) throws Exception { + batteryServiceRegistration.unregister(); + } +} diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/.classpath b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/.classpath new file mode 100644 index 000000000..a95e0906c --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/.project b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/.project new file mode 100644 index 000000000..6b5169a2b --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/.project @@ -0,0 +1,28 @@ + + + org.openhab.training.electricity.dynamicconsumer + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/META-INF/MANIFEST.MF b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/META-INF/MANIFEST.MF new file mode 100644 index 000000000..fcc5c596b --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/META-INF/MANIFEST.MF @@ -0,0 +1,11 @@ +Manifest-Version: 1.0 +Bundle-Name: Dynamic Consumer +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-Vendor: openHAB.org +Bundle-Version: 1.0.0.qualifier +Bundle-ManifestVersion: 2 +Bundle-License: http://www.eclipse.org/legal/epl-v10.html +Bundle-SymbolicName: org.openhab.training.electricity.dynamicconsumer +Import-Package: org.openhab.training.electricity.dynamicconsumer, + org.openhab.training.electricity.provider +Export-Package: org.openhab.training.electricity.dynamicconsumer diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/about.html b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/about.html new file mode 100644 index 000000000..9db40b3c9 --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/about.html @@ -0,0 +1,28 @@ + + + + +About + + +

About This Content

+ +

<September 15, 2014>

+

License

+ +

The openHAB community makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

+ +

If you did not receive this Content directly from the openHAB community, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at openhab.org.

+ + + diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/build.properties b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/build.properties new file mode 100644 index 000000000..5fc538bc8 --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/build.properties @@ -0,0 +1,4 @@ +source.. = src/main/java/ +output.. = target/classes/ +bin.includes = META-INF/,\ + . diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/src/main/java/org/openhab/training/electricity/dynamicconsumer/DynamicConsumer.java b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/src/main/java/org/openhab/training/electricity/dynamicconsumer/DynamicConsumer.java new file mode 100644 index 000000000..02287404b --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.dynamicconsumer/src/main/java/org/openhab/training/electricity/dynamicconsumer/DynamicConsumer.java @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2014-2016 by the respective copyright holders. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.openhab.training.electricity.dynamicconsumer; + +import org.openhab.training.electricity.provider.ElectricityProvider; + +/** + * This interface is used for managing multiple {@link ElectricityProvider}s. + * + * @author Kiril Atanasov - Initial contribution + */ +public interface DynamicConsumer { + + /** + * Adds an {@link ElectricityProvider} to the consumer's available + * providers. + * + * @param electricityProvider + * the specific {@link ElectricityProvider} that will be added. + */ + void providerAdded(ElectricityProvider electricityProvider); + + /** + * Removes an {@link ElectricityProvider} from the consumer's available + * providers. + * + * @param electricityProvider + * the specific {@link ElectricityProvider} that will be removed. + */ + void providerRemoved(ElectricityProvider electricityProvider); + +} diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.provider/about.html b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.provider/about.html index 75fb3cc53..9db40b3c9 100644 --- a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.provider/about.html +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.provider/about.html @@ -1,4 +1,3 @@ - @@ -12,18 +11,18 @@

<September 15, 2014>

License

-

The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +

The openHAB community makes available all content in this plug-in ("Content"). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html. For purposes of the EPL, "Program" will mean the Content.

-

If you did not receive this Content directly from the Eclipse Foundation, the Content is +

If you did not receive this Content directly from the openHAB community, the Content is being redistributed by another party ("Redistributor") and different terms and conditions may apply to your use of any object code in the Content. Check the Redistributor's license that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise indicated below, the terms and conditions of the EPL still apply to any source code in the Content -and such source code may be obtained at http://www.eclipse.org.

+and such source code may be obtained at openhab.org.

diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.provider/src/main/java/org/openhab/training/electricity/provider/ElectricityProvider.java b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.provider/src/main/java/org/openhab/training/electricity/provider/ElectricityProvider.java index 785d65060..078463e0f 100644 --- a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.provider/src/main/java/org/openhab/training/electricity/provider/ElectricityProvider.java +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.provider/src/main/java/org/openhab/training/electricity/provider/ElectricityProvider.java @@ -17,8 +17,8 @@ package org.openhab.training.electricity.provider; public interface ElectricityProvider { /** - * Indicates whether an {@link ElectricityProvider} can provide enough energy - * to a consumer. + * Indicates whether an {@link ElectricityProvider} can provide enough + * energy to a consumer. * * @param value * the energy consumption of the consumer @@ -26,4 +26,12 @@ public interface ElectricityProvider { * requirements, false otherwise */ boolean provide(int value); + + /** + * Returns the type of the {@link ElectricityProvider} from + * {@link ElectricityProviderType}. + * + * @return the type of the {@link ElectricityProvider}. + */ + ElectricityProviderType getType(); } diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.provider/src/main/java/org/openhab/training/electricity/provider/ElectricityProviderType.java b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.provider/src/main/java/org/openhab/training/electricity/provider/ElectricityProviderType.java new file mode 100644 index 000000000..cb7f913b8 --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.provider/src/main/java/org/openhab/training/electricity/provider/ElectricityProviderType.java @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2014-2016 by the respective copyright holders. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.openhab.training.electricity.provider; + +/** + * The type of the {@link ElectricityProvider}. + * + * @author Kiril Atanasov - Initial contribution + */ +public enum ElectricityProviderType { + HOME_NETWORK, + BATTERY, + SOLAR_SOURCE; + } diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/.classpath b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/.classpath new file mode 100644 index 000000000..a95e0906c --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/.project b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/.project new file mode 100644 index 000000000..26072b3a0 --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/.project @@ -0,0 +1,28 @@ + + + org.openhab.training.electricity.tv + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/META-INF/MANIFEST.MF b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/META-INF/MANIFEST.MF new file mode 100644 index 000000000..0048947c5 --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/META-INF/MANIFEST.MF @@ -0,0 +1,17 @@ +Manifest-Version: 1.0 +Bundle-Name: TV +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-Vendor: openHAB.org +Bundle-Version: 1.0.0.qualifier +Bundle-ManifestVersion: 2 +Bundle-License: http://www.eclipse.org/legal/epl-v10.html +Bundle-SymbolicName: org.openhab.training.electricity.tv +Import-Package: org.openhab.training.electricity.battery, + org.openhab.training.electricity.consumer, + org.openhab.training.electricity.dynamicconsumer, + org.openhab.training.electricity.homenetwork, + org.openhab.training.electricity.provider, + org.osgi.framework, + org.osgi.util.tracker, + org.slf4j +Bundle-Activator: org.openhab.training.electricity.tv.TVActivator diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/TVRuntimeEvnironment.launch b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/TVRuntimeEvnironment.launch new file mode 100644 index 000000000..5e6e76e3b --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/TVRuntimeEvnironment.launch @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/about.html b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/about.html new file mode 100644 index 000000000..9db40b3c9 --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/about.html @@ -0,0 +1,28 @@ + + + + +About + + +

About This Content

+ +

<September 15, 2014>

+

License

+ +

The openHAB community makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

+ +

If you did not receive this Content directly from the openHAB community, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at openhab.org.

+ + + diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/build.properties b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/build.properties new file mode 100644 index 000000000..08f06e0e9 --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/build.properties @@ -0,0 +1,4 @@ +source.. = src/main/java +output.. = target/classes +bin.includes = META-INF/,\ + . diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/src/main/java/org/openhab/training/electricity/tv/TV.java b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/src/main/java/org/openhab/training/electricity/tv/TV.java new file mode 100644 index 000000000..468b7862c --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/src/main/java/org/openhab/training/electricity/tv/TV.java @@ -0,0 +1,281 @@ +/** + * Copyright (c) 2014-2016 by the respective copyright holders. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.openhab.training.electricity.tv; + +import java.util.*; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import org.openhab.training.electricity.battery.Battery; +import org.openhab.training.electricity.consumer.ElectricityConsumer; +import org.openhab.training.electricity.dynamicconsumer.DynamicConsumer; +import org.openhab.training.electricity.homenetwork.HomeElectricityNetwork; +import org.openhab.training.electricity.provider.ElectricityProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The class {@link TV} can use two types of {@link ElectricityProvider}s + * -{@link HomeElectricityNetwork} and {@link Battery}, but only one of them at + * a time. The {@link HomeElectricityNetwork} is with priority. If there is no + * {@link ElectricityProvider} or the available {@link ElectricityProvider}(s) + * can't provide enough charge, the {@link TV} waits(doesn't print anything), + * but it is active - if a provider, which could supply enough energy is added + * the TV starts broadcasting. + *

+ * Due to the specifics of the {@link ElectricityProvider} interface all the + * available {@link ElectricityProvider}s will be divided into two groups: + *

    + *
  • {@link #usableProviders} is where all the new providers will be put, the + * {@link TV} will use them until they are depleted, after which they will be + * moved to the other group.
  • + *
  • {@link #depletedProviders} is where all the providers that can't provide + * enough power to run the {@link TV} are.
  • + *
+ * This separation into two groups is made, so that the {@link TV} can keep + * track of which providers are usable and which are depleted. This is very + * important when choosing which {@link ElectricityProvider} to use. + *

+ * In {@link #usableProviders} the {@link ElectricityProvider}s will be ordered + * based on their rating. Their rating will be determined in the + * {@link ProvidersComparatorForTV#getRating(ElectricityProvider)}, based on the + * type of the {@link ElectricityProvider}. If one provider has higher rating + * than another, it must be used before the second. + * + * @author Kiril Atanasov - Initial contribution + * @author Elena Miovska - sorting the {@link ElectricityProvider}s based on + * their type, and picking the {@link #currentElectricityProvider} among + * them. + */ +public class TV implements ElectricityConsumer, DynamicConsumer { + + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + + /** + * Holds all the {@link ElectricityProvider}s the TV can use. They will be + * ordered according to the criteria specified in + * {@link ProvidersComparatorForTV}. + */ + protected PriorityQueue usableProviders = new PriorityQueue<>(new ProvidersComparatorForTV()); + + /** A list of the depleted {@link ElectricityProvider}s */ + protected List depletedProviders = new ArrayList<>(); + + /** + * The {@link ElectricityProvider} that the TV uses at the moment, the one + * it will try to utilize. + */ + protected ElectricityProvider currentElectricityProvider; + + /** The power consumption of the TV */ + protected final int TV_CONSUMPTION = 10; + + /** The time (in seconds) the TV waits before trying to use a provider */ + protected final int BROADCASTING_PERIOD = 5; + + /** + * {@inheritDoc} + *

+ * After the {@link ElectricityProvider} has been added we check if the + * {@link #currentElectricityProvider} should be changed. + */ + @Override + public synchronized void providerAdded(ElectricityProvider electricityProvider) { + usableProviders.add(electricityProvider); + if (shouldTheCurrentProviderBeChanged(electricityProvider)) { + setCurrentProvider(); + } + } + + /** + * Determines if the {@link #currentElectricityProvider} should be changed, + * when adding a new {@link ElectricityProvider}. + * + * @param electricityProvider + * the {@link ElectricityProvider} that has been added. + * @return true if {@link #currentElectricityProvider} should be changed, + * false otherwise. + */ + private boolean shouldTheCurrentProviderBeChanged(ElectricityProvider electricityProvider) { + return currentElectricityProvider == null || ProvidersComparatorForTV + .isTheSecondProviderWithHigherPriority(currentElectricityProvider, electricityProvider); + } + + /** + * {@inheritDoc} + *

+ * If the electricityProvider, which is being removed is also the + * {@link #currentElectricityProvider} then the + * {@link #currentElectricityProvider} is set to {@code null}. + * + * @param electricityProvider + * the {@link ElectricityProvider} service which has been removed + */ + @Override + public synchronized void providerRemoved(ElectricityProvider electricityProvider) { + if (usableProviders.contains(electricityProvider)) { + usableProviders.remove(electricityProvider); + } else { + depletedProviders.remove(electricityProvider); + } + + if (currentElectricityProvider == electricityProvider) { + removeCurrentElectricityProvider(); + } + } + + /** + * Changes the {@link #currentElectricityProvider} to another + * {@link #currentElectricityProvider}. + */ + protected void removeCurrentElectricityProvider() { + logger.info("provider {} is no longer available. ", currentElectricityProvider.toString()); + setCurrentProvider(); + } + + /** + * The {@link #currentElectricityProvider} is set to be the head of the + * {@link #usableProviders} or {@code null} if there are no usable + * providers. + */ + public void setCurrentProvider() { + setCurrentProvider(usableProviders.peek()); + } + + @Override + public void setCurrentProvider(ElectricityProvider electricityProvider) { + currentElectricityProvider = electricityProvider; + } + + /** + * {@inheritDoc} + *

+ * The TV starts the scheduler. The scheduler starts running and will run + * until given the shutdownNow() command. + */ + @Override + public void start() { + scheduler.scheduleAtFixedRate(broadcastingAction, 0, BROADCASTING_PERIOD, TimeUnit.SECONDS); + } + + /** + * {@inheritDoc} + *

+ * The TV invokes the {@link #scheduler}'s stop method, otherwise the + * {@link #scheduler} will continue running even after the {@link TV} bundle + * is stopped. + */ + @Override + public void stop() { + scheduler.shutdownNow(); + } + + @Override + public List getAllAvailableProviders() { + return new ArrayList(usableProviders); + } + + /** + * It is not advised to start a Thread on its own. That's why we are using a + * ScheduledExecutorService. It will be able to run only one Thread at a + * time. + */ + protected final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); + + /** + * {@link #broadcastingAction} checks if there are any + * {@link ElectricityProvider}s in {@link #usableProviders}. If so this + * means the {@link TV} could be able to broadcast. If an + * {@link ElectricityProvider} gets depleted it is moved to the + * {@link #depletedProviders} and a message is being displayed. + */ + protected Runnable broadcastingAction = new Runnable() { + + @Override + public void run() { + synchronized (TV.this) { + if (!usableProviders.isEmpty()) { + if (currentElectricityProvider.provide(TV_CONSUMPTION)) { + actWhenPowered(); + } else { + actWhenNotPowered(); + moveProviderFromUsableToDepleted(currentElectricityProvider); + } + } + } + } + }; + + /** What will the {@link TV} do when it has enough power. */ + protected void actWhenPowered() { + // Displaying a message which provider is in use. + logger.info("broadcasting on {}", currentElectricityProvider.getClass().getName()); + } + + /** + * What will the {@link TV} do when it has {@link ElectricityProvider} but + * not enough power. + */ + protected void actWhenNotPowered() { + // Displaying a message that the provider in use has been depleted. + logger.info("provider {} is depleted. ", currentElectricityProvider.toString()); + + } + + /** + * Moves an {@link ElectricityProvider} from {@link #usableProviders} to + * {@link #depletedProviders}. If the {@link #usableProviders} is empty it + * displays a notification message. + * + * @param electricityProvider + * the {@link ElectricityProvider} that must be moved. + */ + protected void moveProviderFromUsableToDepleted(ElectricityProvider electricityProvider) { + usableProviders.remove(electricityProvider); + depletedProviders.add(electricityProvider); + if (usableProviders.isEmpty()) { + logger.info("There are no more usable providers"); + } else { + setCurrentProvider(); + } + } + + @Override + public ElectricityProvider getCurrentElectricityProvider() { + return this.currentElectricityProvider; + } +} + +/** + * This class will implement the logic by which the {@link ElectricityProvider}s + * will be arranged in {@link #usableProviders}. + */ +class ProvidersComparatorForTV implements Comparator { + + @Override + public int compare(ElectricityProvider first, ElectricityProvider second) { + return getRating(second) - getRating(first); + } + + public static boolean isTheSecondProviderWithHigherPriority(ElectricityProvider first, ElectricityProvider second) { + return getRating(first) - getRating(second) < 0; + } + + public static int getRating(ElectricityProvider electricityProvider) { + switch (electricityProvider.getType()) { + case HOME_NETWORK: + return 1000; + case BATTERY: + return 500; + default: + return 0; + } + } +} diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/src/main/java/org/openhab/training/electricity/tv/TVActivator.java b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/src/main/java/org/openhab/training/electricity/tv/TVActivator.java new file mode 100644 index 000000000..8852f7044 --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/src/main/java/org/openhab/training/electricity/tv/TVActivator.java @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2014-2016 by the respective copyright holders. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.openhab.training.electricity.tv; + +import org.openhab.training.electricity.consumer.ElectricityConsumer; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +/** + * The class {@link TVActivator} is responsible for the activation of this + * bundle. + * + * @author Kiril Atanasov - Initial contribution + */ +public class TVActivator implements BundleActivator { + + private TvPowerProviderTracker tracker; + + private ServiceRegistration tvServiceRegistration; + + /** + * {@inheritDoc} + *

+ * Registers a TV and a TVServiceTracker service. + */ + @SuppressWarnings("unchecked") + @Override + public void start(BundleContext context) throws Exception { + // A TV instance. We could register a service with it + TV tv = new TV(); + + // Registering the TV Service + tvServiceRegistration = (ServiceRegistration) context.registerService(ElectricityConsumer.class.getName(), + tv, null); + + /* + * we are linking the reference to an actual {@link TVServiceTracker} + * object + */ + tracker = new TvPowerProviderTracker(context, tv); + + tracker.open(); + + // The TV is starting to consume power from the providers + tracker.getTV().start(); + + } + + /** + * {@inheritDoc} + *

+ * Stops and unregisters the TVServiceTracker service. Unregistering the TV + * Service. + */ + @Override + public void stop(BundleContext context) throws Exception { + tracker.getTV().stop(); + tvServiceRegistration.unregister(); + tracker.close(); + } + +} diff --git a/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/src/main/java/org/openhab/training/electricity/tv/TvPowerProviderTracker.java b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/src/main/java/org/openhab/training/electricity/tv/TvPowerProviderTracker.java new file mode 100644 index 000000000..23a7c6b79 --- /dev/null +++ b/_sample_code/osgi_codings_tasks/bundles/org.openhab.training.electricity.tv/src/main/java/org/openhab/training/electricity/tv/TvPowerProviderTracker.java @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2014-2016 by the respective copyright holders. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.openhab.training.electricity.tv; + +import org.openhab.training.electricity.provider.ElectricityProvider; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.util.tracker.ServiceTracker; + +/** + * The class {@link TvPowerProviderTracker} is tracking all the services which + * implement the {@link ElectricityProvider} interface. + * + * @author Kiril Atanasov - Initial contribution + */ +public class TvPowerProviderTracker extends ServiceTracker { + + /** + * The ServiceTracker will add/remove/modify providers of the {@link #tv}. + */ + private TV tv = null; + + /** + * This constructor sets ServiceTracker to track all the services using the + * {@link ElectricityProvider} interface. + *

+ * All the services, which don't implement the {@link ElectricityProvider} + * interface or aren't registered won't be tracked by + * {@link TvPowerProviderTracker}. + * + * @param context + * the bundle context, usually injected by the BundleActivator + * @param tv + * the {@link TV} object to which the ServiceTracker will add, + * remove or modify {@link ElectricityProvider}(s). + */ + public TvPowerProviderTracker(BundleContext context, TV tv) { + super(context, ElectricityProvider.class.getName(), null); + this.tv = tv; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public Object addingService(ServiceReference reference) { + ElectricityProvider provider = (ElectricityProvider) context.getService(reference); + tv.providerAdded(provider); + /* + * This method must return the service object for the specified + * ServiceReference and in our case that is provider. + */ + return provider; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public void removedService(ServiceReference reference, Object service) { + ElectricityProvider provider = (ElectricityProvider) context.getService(reference); + tv.providerRemoved(provider); + context.ungetService(reference); + } + + /** + * {@inheritDoc} + *

+ * This service will be called when the modified functions of a tracked + * service is called. The modified function is defined with declarative + * services. + */ + @SuppressWarnings("rawtypes") + @Override + public void modifiedService(ServiceReference reference, Object service) { + /* This method will not be used in this implementation */ + } + + public TV getTV() { + return this.tv; + } +}