diff --git a/CODEOWNERS b/CODEOWNERS index b927bfb8487..44604919af1 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -183,7 +183,6 @@ /bundles/org.openhab.binding.jablotron/ @octa22 /bundles/org.openhab.binding.jeelink/ @vbier /bundles/org.openhab.binding.jellyfin/ @GiviMAD -/bundles/org.openhab.binding.juicenet/ @jsjames /bundles/org.openhab.binding.kaleidescape/ @mlobstein /bundles/org.openhab.binding.keba/ @kgoderis /bundles/org.openhab.binding.km200/ @Markinus diff --git a/bom/openhab-addons/pom.xml b/bom/openhab-addons/pom.xml index 71229846b00..56783211f63 100644 --- a/bom/openhab-addons/pom.xml +++ b/bom/openhab-addons/pom.xml @@ -901,11 +901,6 @@ org.openhab.binding.jellyfin ${project.version} - - org.openhab.addons.bundles - org.openhab.binding.juicenet - ${project.version} - org.openhab.addons.bundles org.openhab.binding.kaleidescape diff --git a/bundles/org.openhab.binding.juicenet/NOTICE b/bundles/org.openhab.binding.juicenet/NOTICE deleted file mode 100644 index 38d625e3492..00000000000 --- a/bundles/org.openhab.binding.juicenet/NOTICE +++ /dev/null @@ -1,13 +0,0 @@ -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 diff --git a/bundles/org.openhab.binding.juicenet/README.md b/bundles/org.openhab.binding.juicenet/README.md deleted file mode 100644 index fc727d62f9d..00000000000 --- a/bundles/org.openhab.binding.juicenet/README.md +++ /dev/null @@ -1,268 +0,0 @@ -# JuiceNet Binding - -The JuiceNet binding will interface with the cloud portal to get status and manage your JuiceBox EV charger(s). -In addition to getting the status of various items from the EV charger, it is also possible to start and stop charging sessions. - -## Supported Things - -This binding supports the following things: - -| thing | type | description | -|---------- |-------- |------------------------------ | -| JuiceNet Account | Bridge | This represents the cloud account to interface with the JuiceNet API. | -| JuiceBox EV Charger | Device | This interfaces to a specific JuiceBox EV charger associated with the JuiceNet account. | - -This binding should work with multiple JuiceBox EV chargers associated with the account, however it is currently only tested with a single EV charger. - -### Discovery - -Once a JuiceNet Account bridge has been created, any JuiceBox EV Chargers associated with this account will be discovered. - -### Thing Configuration - -The configuration required is to create a JuiceNet account thing and fill in the appropriate API token. -The API token can be found on the Account page at . - -A JuiceBox EV Charger requires a unitID which can also be found in the device settings at the JuiceNet web page. - -## Channels - -| channel | type | read-only | description | -|---------- |-------- |--------- | ------- | -| name | String | Y | Name of device.| -| chargingState | String | N | Current charging state (Start Charging, Smart Charging, Stop Charging). | -| state | String | Y | This is the current device state (Available, Plugged-In, Charging, Error, Disconnected). | -| message | String | Y | This is a message detailing the state of the EV charger. | -| override | Switch | N | Smart charging is overridden. Set to "OFF" to remove override. | -| chargingTimeLeft | Number:Time | Y | Charging time left (seconds). | -| plugUnplugTime | DateTime | Y | Last time of either plug-in or plug-out. | -| targetTime | DateTime | N | “Start charging” start time, or time to start when overriding smart charging. | -| unitTime | DateTime | Y | Current time on the unit. | -| temperature | Number:Temperature | Y | Current temperature at the unit. | -| currentLimit | Number:ElectricCurrent | N | Max charging current allowed. | -| current | Number:ElectricCurrent | Y | Current charging current. | -| voltage | Number:ElectricPotential | Y | Current voltage. | -| energy | Number:Energy | Y | Current amount of energy poured to the vehicle. | -| savings | Number | Y | Current session EV savings. | -| power | Number:Power | Y | Current charging power. | -| secondsCharging | Number:Time | Y | Charging time since plug-in time. | -| energyAtPlugin | Number:Energy | Y | Energy value at the plugging time. | -| energyToAdd | Number:Energy | N | Amount of energy to be added in current session. | -| lifetimeEnergy | Number:Energy | Y | Total energy delivered to vehicles during lifetime. | -| lifetimeSavings | Number | Y | EV driving saving during lifetime. | -| gasCost | Number | Y | Cost of gasoline used in savings calculations. | -| fuelConsumption | Number | Y | Miles per gallon used in savings calculations. | -| ecost | Number | Y | Cost of electricity from utility company. (currency/kWh) | -| energyPerMile | Number | Y | Energy per mile. | -| carDescription | String | Y | Car description of vehicle currently or last charged. | -| carBatterySize | Number:Energy | Y | Car battery pack size. | -| carBatteryRange | Number:Length | Y | Car range. | -| carChargingRate | Number:Power | Y | Car charging rate. | - -## Full Example - -### Things File - -If configuring the binding with manual configuration an example thing file looks like this: - -```java -Bridge juicenet:account:myaccount [ apiToken="xxxx-xxxx-xxxx-xxxx-xxxxx" ] { - Thing device JamesCharger [ unitID="xxxxxxx" ] -} -``` - -### Items File - -An example of an items file is here. - -```java -String JuiceNet_Name "Name" { channel="juicenet:device:myaccount:JamesCharger:name" } -String JuiceNet_State "Device State" { channel="juicenet:device:myaccount:JamesCharger:state" } -String JuiceNet_ChargingState "Charging State" { channel="juicenet:device:myaccount:JamesCharger:chargingState" } -String JuiceNet_Message "State Message" { channel="juicenet:device:myaccount:JamesCharger:message" } -Switch JuiceNet_Override "Override State" { channel="juicenet:device:myaccount:JamesCharger:override" } -DateTime JuiceNet_PlutUnplugTime "Plug/Unplug Time [%1$tB %1$te, %1$tY %1$tl:%1$tM %1$tp]" { channel="juicenet:device:myaccount:JamesCharger:plugUnplugTime" } -DateTime JuiceNet_TargetTime "Target Time [%1$tB %1$te, %1$tY %1$tl:%1$tM %1$tp]" { channel="juicenet:device:myaccount:JamesCharger:targetTime" } -Number:Time JuiceNet_ChargingTimeLeft "Charging Time Left [%.0f %unit%]" { channel="juicenet:device:myaccount:JamesCharger:chargingTimeLeft" } -DateTime JuiceNet_UnitTime "Unit Time [%1$tB %1$te, %1$tY %1$tl:%1$tM %1$tp]" { channel="juicenet:device:myaccount:JamesCharger:unitTime" } -Number:Temperature JuiceNet_Temperature "Temperature [%.0f %unit%]" { channel="juicenet:device:myaccount:JamesCharger:temperature" } -Number:ElectricCurrent JuiceNet_CurrentLimit "Current Limit [%d %unit%]" { channel="juicenet:device:myaccount:JamesCharger:currentLimit" } -Number:ElectricCurrent JuiceNet_Current "Current [%.1f %unit%]" { channel="juicenet:device:myaccount:JamesCharger:current" } -Number:ElectricPotential JuiceNet_Voltage "Voltage [%d %unit%]" { channel="juicenet:device:myaccount:JamesCharger:voltage" } -Number:Energy JuiceNet_Energy "Current Energy [%.1f %unit%]" { channel="juicenet:device:myaccount:JamesCharger:energy" } -Number:Power JuiceNet_Power "Charging Power [%.2f %unit%]" { channel="juicenet:device:myaccount:JamesCharger:power" } -Number JuiceNet_Savings "Savings [$%.2f]" { channel="juicenet:device:myaccount:JamesCharger:savings" } -Number:Time JuiceNet_ChargingTime "Charging Time [%.0f %unit%]" { channel="jjuicenet:device:myaccount:JamesCharger:chargingTime" } -Number:Energy JuiceNet_EnergyToAdd "Energy to Add [%.2f %unit%]" { channel="juicenet:device:myaccount:JamesCharger:energyToAdd" } -Number:Energy JuiceNet_EnergyAtPlugin "Energy at Plugin [%.2f %unit%]" { channel="juicenet:device:myaccount:JamesCharger:energyAtPlugin" } -Number:Energy JuiceNet_LifetimeEnergy "Lifetime Energy [%.2f %unit%]" { channel="juicenet:device:myaccount:JamesCharger:lifetimeEnergy" } -Number JuiceNet_GasCost "Gas Cost [$%.2f]" { channel="juicenet:device:myaccount:JamesCharger:gasCost" } -Number JuiceNet_FuelConsumption "Fuel consumption [%.1f %unit%]" { channel="juicenet:device:myaccount:JamesCharger:fuelConsumption" } -Number JuiceNet_Ecost "Utility Energy Cost [$%.2f]" { channel="juicenet:device:myaccount:JamesCharger:ecost" } -Number JuiceNet_LifetimeSavings "Lifetime Savings [$%.2f]" { channel="juicenet:device:myaccount:JamesCharger:lifetimeSavings" } -Number:Power JuiceNet_EnergyPerMile "Energy Hours Per Mile [%.2f %unit%]" { channel="juicenet:device:myaccount:JamesCharger:energyPerMile" } -String JuiceNet_CarDescription "Car Description" { channel="juicenet:device:myaccount:JamesCharger:carDescription" } -Number:Length JuiceNet_CarBatteryRange "Mileage Range [%d %unit%]" { channel="juicenet:device:myaccount:JamesCharger:carBatteryRange" } -Number:Energy JuiceNet_CarBatterySize "Car Battery Pack Size [%.2f %unit%]" { channel="juicenet:device:myaccount:JamesCharger:carBatterySize" } -Number:Power JuiceNet_CarChargineRage "Car Charging Rate [%.2f %unit%]" { channel="juicenet:device:myaccount:JamesCharger:carChargingRate" } - -``` - -## Widget - -The following custom widget can be used with this binding. - -![JuiceBox Widget](doc/widget.png) - -```yaml -uid: widget_JuiceBox -tags: [] -props: - parameters: - - description: Prefix for the items with the data - label: Item prefix - name: prefix - required: false - type: TEXT - parameterGroups: [] -timestamp: May 10, 2021, 2:38:55 PM -component: f7-card -config: - title: =items[props.prefix + "_Name"].state - style: - border-radius: var(--f7-card-expandable-border-radius) - --f7-card-header-border-color: none -slots: - default: - - component: f7-card-content - slots: - default: - - component: f7-row - config: - class: - - display-flex - - align-content-stretch - - align-items-center - slots: - default: - - component: f7-gauge - config: - type: semicircle - size: 270 - value: =Number.parseFloat(items[props.prefix + "_CurrentEnergy"].state) / Number.parseFloat(items[props.prefix + "_CarBatteryPackSize"].state) - bg-color: transparent - border-bg-color: '=(items[props.prefix + "_DeviceState"].state === "charging") ? "#577543" : (items[props.prefix + "_DeviceState"].state === "plugged") ? "#8f6c2f" : "#595959"' - border-color: '=(items[props.prefix + "_DeviceState"].state === "charging") ? "#90d164" : (items[props.prefix + "_DeviceState"].state === "plugged") ? "#ed9c11" : "#adadad"' - borderWidth: 40 - value-text: =items[props.prefix + "_CurrentEnergy"].displayState - value-text-color: '=(items[props.prefix + "_DeviceState"].state === "charging") ? "#90d164" : (items[props.prefix + "_DeviceState"].state === "plugged") ? "#ed9c11" : "#adadad"' - value-font-size: 20 - value-font-weight: 500 - label-text: =items[props.prefix + "_DeviceState"].displayState - label-text-color: white - label-font-size: 18 - label-font-weight: 400 - noBorder: true - outline: true - - component: f7-row - config: - class: - - display-flex - - justify-content-center - - align-content-stretch - - align-items-center - - margin-left - slots: - default: - - component: f7-segmented - config: - strong: true - style: - width: 80% - slots: - default: - - component: oh-button - config: - text: Start - color: blue - size: 24 - active: =(items[props.prefix + "_ChargingState"].state === "start") - action: command - actionItem: =props.prefix + "_ChargingState" - actionCommand: start - - component: oh-button - config: - text: Smart - color: blue - size: 24 - active: =(items[props.prefix + "_ChargingState"].state === 'smart') - action: command - actionItem: =props.prefix + "_ChargingState" - actionCommand: smart - - component: oh-button - config: - text: Stop - color: blue - size: 24 - active: =(items[props.prefix + "_ChargingState"].state === "stop") - action: command - actionItem: =props.prefix + "_ChargingState" - actionCommand: stop - - component: f7-row - config: - class: - - display-flex - - justify-content-space-evenly - - align-content-stretch - - align-items-center - - height: 40px - style: - --f7-chip-font-size: 14px - --f7-chip-height: 28px - padding-top: 12px - slots: - default: - - component: f7-chip - config: - visible: =(items[props.prefix + "_DeviceState"].state === "charging") - text: '="Power: " + items[props.prefix + "_ChargingPower"].state' - iconF7: bolt_fill - media-bg-color: blue - bg-color: gray - label: hello - style: - padding-rightc: 12px - - component: f7-chip - config: - visible: =(items[props.prefix + "_DeviceState"].state === "charging") - text: '="Current: " + items[props.prefix + "_Current"].state' - iconF7: arrow_up_circl - media-bg-color: blue - bg-color: gray - - component: f7-chip - config: - text: '="Voltage: " + items[props.prefix + "_Voltage"].state' - iconF7: plusminus - media-bg-color: blue - bg-color: gray - - component: f7-chip - config: - visible: =(items[props.prefix + "_ChargingState"].state === 'smart') - text: '="Charge at: " + items[props.prefix + "_TargetTime"].displayState' - iconF7: clock - media-bg-color: blue - bg-color: gray - - component: f7-chip - config: - visible: =(items[props.prefix + "_DeviceState"].state === 'charging') - text: '="Charge Time Left: " + items[props.prefix + "_ChargingTimeLeft"].displayState' - iconF7: timer - media-bg-color: blue - bg-color: gray - - component: f7-card-footer - slots: - default: - - component: Label - config: - text: =items[props.prefix + "_CarDescription"].state -``` diff --git a/bundles/org.openhab.binding.juicenet/doc/widget.png b/bundles/org.openhab.binding.juicenet/doc/widget.png deleted file mode 100644 index 708e5b413d2..00000000000 Binary files a/bundles/org.openhab.binding.juicenet/doc/widget.png and /dev/null differ diff --git a/bundles/org.openhab.binding.juicenet/pom.xml b/bundles/org.openhab.binding.juicenet/pom.xml deleted file mode 100644 index bbfb649d4eb..00000000000 --- a/bundles/org.openhab.binding.juicenet/pom.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - 4.0.0 - - - org.openhab.addons.bundles - org.openhab.addons.reactor.bundles - 5.0.0-SNAPSHOT - - - org.openhab.binding.juicenet - - openHAB Add-ons :: Bundles :: JuiceNet Binding - diff --git a/bundles/org.openhab.binding.juicenet/src/main/docs/JuiceNet API_client_12_11_2017.docx b/bundles/org.openhab.binding.juicenet/src/main/docs/JuiceNet API_client_12_11_2017.docx deleted file mode 100644 index ff9a2ae3781..00000000000 Binary files a/bundles/org.openhab.binding.juicenet/src/main/docs/JuiceNet API_client_12_11_2017.docx and /dev/null differ diff --git a/bundles/org.openhab.binding.juicenet/src/main/feature/feature.xml b/bundles/org.openhab.binding.juicenet/src/main/feature/feature.xml deleted file mode 100644 index 9dafc20b273..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/feature/feature.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features - - - openhab-runtime-base - mvn:org.openhab.addons.bundles/org.openhab.binding.juicenet/${project.version} - - diff --git a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/JuiceNetBindingConstants.java b/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/JuiceNetBindingConstants.java deleted file mode 100644 index 574704ec19a..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/JuiceNetBindingConstants.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2010-2025 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.juicenet.internal; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.core.thing.ThingTypeUID; - -/** - * The {@link JuiceNetBindingConstants} class defines common constants, which are - * used across the whole binding. - * - * @author Jeff James - Initial contribution - */ -@NonNullByDefault -public class JuiceNetBindingConstants { - private static final String BINDING_ID = "juicenet"; - - // List of Bridge Type - public static final String BRIDGE = "account"; - - // List of all Device Types - public static final String DEVICE = "device"; - - // List of all Bridge Thing Type UIDs - public static final ThingTypeUID BRIDGE_THING_TYPE = new ThingTypeUID(BINDING_ID, BRIDGE); - - // List of all Thing Type UIDs - public static final ThingTypeUID DEVICE_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE); - - // Device config parameter - public static final String PARAMETER_UNIT_ID = "unitID"; - - // Device properties - public static final String PROPERTY_NAME = "name"; - - // List of all Channel ids - public static final String CHANNEL_NAME = "name"; - public static final String CHANNEL_CHARGING_STATE = "chargingState"; - public static final String CHANNEL_STATE = "state"; - public static final String CHANNEL_MESSAGE = "message"; - public static final String CHANNEL_OVERRIDE = "override"; - public static final String CHANNEL_CHARGING_TIME_LEFT = "chargingTimeLeft"; - public static final String CHANNEL_PLUG_UNPLUG_TIME = "plugUnplugTime"; - public static final String CHANNEL_TARGET_TIME = "targetTime"; - public static final String CHANNEL_UNIT_TIME = "unitTime"; - public static final String CHANNEL_TEMPERATURE = "temperature"; - public static final String CHANNEL_CURRENT_LIMIT = "currentLimit"; - public static final String CHANNEL_CURRENT = "current"; - public static final String CHANNEL_VOLTAGE = "voltage"; - public static final String CHANNEL_ENERGY = "energy"; - public static final String CHANNEL_SAVINGS = "savings"; - public static final String CHANNEL_POWER = "power"; - public static final String CHANNEL_CHARGING_TIME = "chargingTime"; - public static final String CHANNEL_ENERGY_AT_PLUGIN = "energyAtPlugin"; - public static final String CHANNEL_ENERGY_TO_ADD = "energyToAdd"; - public static final String CHANNEL_LIFETIME_ENERGY = "lifetimeEnergy"; - public static final String CHANNEL_LIFETIME_SAVINGS = "lifetimeSavings"; - - public static final String CHANNEL_GAS_COST = "gasCost"; - public static final String CHANNEL_FUEL_CONSUMPTION = "fuelConsumption"; - public static final String CHANNEL_ECOST = "ecost"; - public static final String CHANNEL_ENERGY_PER_MILE = "energyPerMile"; - - public static final String CHANNEL_CAR_DESCRIPTION = "carDescription"; - public static final String CHANNEL_CAR_BATTERY_SIZE = "carBatterySize"; - public static final String CHANNEL_CAR_BATTERY_RANGE = "carBatteryRange"; - public static final String CHANNEL_CAR_CHARGING_RATE = "carChargingRate"; -} diff --git a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/JuiceNetHandlerFactory.java b/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/JuiceNetHandlerFactory.java deleted file mode 100644 index 4029478d4ad..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/JuiceNetHandlerFactory.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2010-2025 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.juicenet.internal; - -import static org.openhab.binding.juicenet.internal.JuiceNetBindingConstants.*; - -import java.util.Set; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.openhab.binding.juicenet.internal.handler.JuiceNetBridgeHandler; -import org.openhab.binding.juicenet.internal.handler.JuiceNetDeviceHandler; -import org.openhab.core.io.net.http.HttpClientFactory; -import org.openhab.core.thing.Bridge; -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 JuiceNetHandlerFactory} is responsible for creating things and thing - * handlers. - * - * @author Jeff James - Initial contribution - */ -@NonNullByDefault -@Component(configurationPid = "binding.juicenet", service = ThingHandlerFactory.class) -public class JuiceNetHandlerFactory extends BaseThingHandlerFactory { - - private static final Set SUPPORTED_THING_TYPES_UIDS = Set.of(BRIDGE_THING_TYPE, DEVICE_THING_TYPE); - private final HttpClientFactory httpClientFactory; - - @Activate - public JuiceNetHandlerFactory(@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 (thingTypeUID.equals(BRIDGE_THING_TYPE)) { - return new JuiceNetBridgeHandler((Bridge) thing, httpClientFactory.getCommonHttpClient()); - } else if (thingTypeUID.equals(DEVICE_THING_TYPE)) { - return new JuiceNetDeviceHandler(thing); - } - - return null; - } -} diff --git a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/JuiceNetApi.java b/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/JuiceNetApi.java deleted file mode 100644 index deda05dd713..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/JuiceNetApi.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (c) 2010-2025 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.juicenet.internal.api; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -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.HttpHeader; -import org.eclipse.jetty.http.HttpStatus; -import org.openhab.binding.juicenet.internal.api.dto.JuiceNetApiDevice; -import org.openhab.binding.juicenet.internal.api.dto.JuiceNetApiDeviceStatus; -import org.openhab.binding.juicenet.internal.api.dto.JuiceNetApiInfo; -import org.openhab.binding.juicenet.internal.api.dto.JuiceNetApiTouSchedule; -import org.openhab.core.thing.ThingUID; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.JsonSyntaxException; - -/** - * The {@link JuiceNetApi} is responsible for implementing the api interface to the JuiceNet cloud server - * - * @author Jeff James - Initial contribution - */ -@NonNullByDefault -public class JuiceNetApi { - private final Logger logger = LoggerFactory.getLogger(JuiceNetApi.class); - - private static final String API_HOST = "https://jbv1-api.emotorwerks.com/"; - private static final String API_ACCOUNT = API_HOST + "box_pin"; - private static final String API_DEVICE = API_HOST + "box_api_secure"; - private static final int REQUEST_TIMEOUT_MS = 10_000; - - private String apiToken = ""; - private HttpClient httpClient; - private ThingUID bridgeUID; - - public enum ApiCommand { - GET_ACCOUNT_UNITS("get_account_units", API_ACCOUNT), - GET_STATE("get_state", API_DEVICE), - SET_CHARGING_LIMIT("set_limit", API_DEVICE), - GET_SCHEDULE("get_schedule", API_DEVICE), - SET_SCHEDULE("set_schedule", API_DEVICE), - GET_INFO("get_info", API_DEVICE), - SET_OVERRIDE("set_override", API_DEVICE); - - final String command; - final String uri; - - ApiCommand(String command, String uri) { - this.command = command; - this.uri = uri; - } - } - - public JuiceNetApi(HttpClient httpClient, ThingUID bridgeUID) { - this.bridgeUID = bridgeUID; - this.httpClient = httpClient; - } - - public void setApiToken(String apiToken) { - this.apiToken = apiToken; - } - - public List queryDeviceList() throws JuiceNetApiException, InterruptedException { - JuiceNetApiDevice[] listDevices; - try { - JsonObject jsonResponse = postApiCommand(ApiCommand.GET_ACCOUNT_UNITS, null); - - JsonElement unitsElement = jsonResponse.get("units"); - if (unitsElement == null) { - throw new JuiceNetApiException("getDevices from Juicenet API failed, no 'units' element in response."); - } - - listDevices = new Gson().fromJson(unitsElement.getAsJsonArray(), JuiceNetApiDevice[].class); - } catch (JsonSyntaxException e) { - throw new JuiceNetApiException("getDevices from JuiceNet API failed, invalid JSON list."); - } catch (IllegalStateException e) { - throw new JuiceNetApiException("getDevices from JuiceNet API failed - did not return valid array."); - } - - return Arrays.asList(listDevices); - } - - public JuiceNetApiDeviceStatus queryDeviceStatus(String token) throws JuiceNetApiException, InterruptedException { - JuiceNetApiDeviceStatus deviceStatus; - try { - JsonObject jsonResponse = postApiCommand(ApiCommand.GET_STATE, token); - - deviceStatus = new Gson().fromJson(jsonResponse, JuiceNetApiDeviceStatus.class); - } catch (JsonSyntaxException e) { - throw new JuiceNetApiException("queryDeviceStatus from JuiceNet API failed, invalid JSON list."); - } catch (IllegalStateException e) { - throw new JuiceNetApiException("queryDeviceStatus from JuiceNet API failed - did not return valid array."); - } - - return Objects.requireNonNull(deviceStatus); - } - - public JuiceNetApiInfo queryInfo(String token) throws InterruptedException, JuiceNetApiException { - JuiceNetApiInfo info; - try { - JsonObject jsonResponse = postApiCommand(ApiCommand.GET_INFO, token); - - info = new Gson().fromJson(jsonResponse, JuiceNetApiInfo.class); - } catch (JsonSyntaxException e) { - throw new JuiceNetApiException("queryInfo from JuiceNet API failed, invalid JSON list."); - } catch (IllegalStateException e) { - throw new JuiceNetApiException("queryInfo from JuiceNet API failed - did not return valid array."); - } - - return Objects.requireNonNull(info); - } - - public JuiceNetApiTouSchedule queryTOUSchedule(String token) throws InterruptedException, JuiceNetApiException { - JuiceNetApiTouSchedule deviceTouSchedule; - try { - JsonObject jsonResponse = postApiCommand(ApiCommand.GET_SCHEDULE, token); - - deviceTouSchedule = new Gson().fromJson(jsonResponse, JuiceNetApiTouSchedule.class); - } catch (JsonSyntaxException e) { - throw new JuiceNetApiException("queryTOUSchedule from JuiceNet API failed, invalid JSON list."); - } catch (IllegalStateException e) { - throw new JuiceNetApiException("queryTOUSchedule from JuiceNet API failed - did not return valid array."); - } - - return Objects.requireNonNull(deviceTouSchedule); - } - - public void setOverride(String token, int energy_at_plugin, Long override_time, int energy_to_add) - throws InterruptedException, JuiceNetApiException { - Map params = new HashMap<>(); - - params.put("energy_at_plugin", Integer.toString(energy_at_plugin)); - params.put("override_time", Long.toString(override_time)); - params.put("energy_to_add", Integer.toString(energy_to_add)); - - postApiCommand(ApiCommand.SET_OVERRIDE, token, params); - } - - public void setCurrentLimit(String token, int limit) throws InterruptedException, JuiceNetApiException { - Map params = new HashMap<>(); - - params.put("amperage", Integer.toString(limit)); - - postApiCommand(ApiCommand.SET_OVERRIDE, token, params); - } - - public JsonObject postApiCommand(ApiCommand cmd, @Nullable String token) - throws InterruptedException, JuiceNetApiException { - Map params = new HashMap<>(); - - return postApiCommand(cmd, token, params); - } - - public JsonObject postApiCommand(ApiCommand cmd, @Nullable String token, Map params) - throws InterruptedException, JuiceNetApiException { - Request request = httpClient.POST(cmd.uri); - request.timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); - request.header(HttpHeader.CONTENT_TYPE, "application/json"); - - // Add required params - params.put("cmd", cmd.command); - params.put("device_id", bridgeUID.getAsString()); - params.put("account_token", apiToken); - - if (token != null) { - params.put("token", token); - } - - JsonObject jsonResponse; - try { - request.content(new StringContentProvider(new Gson().toJson(params)), "application/json"); - ContentResponse response = request.send(); - if (response.getStatus() != HttpStatus.OK_200) { - throw new JuiceNetApiException( - cmd.command + "from JuiceNet API unsuccessful, please check configuation. (HTTP code :" - + response.getStatus() + ")."); - } - - String responseString = response.getContentAsString(); - logger.trace("{}", responseString); - - jsonResponse = JsonParser.parseString(responseString).getAsJsonObject(); - JsonElement successElement = jsonResponse.get("success"); - if (successElement == null) { - throw new JuiceNetApiException( - cmd.command + " from JuiceNet API failed, 'success' element missing from response."); - } - boolean success = successElement.getAsBoolean(); - - if (!success) { - throw new JuiceNetApiException(cmd.command + " from JuiceNet API failed, please check configuration."); - } - } catch (IllegalStateException e) { - throw new JuiceNetApiException(cmd.command + " from JuiceNet API failed, invalid JSON."); - } catch (TimeoutException e) { - throw new JuiceNetApiException(cmd.command + " from JuiceNet API timeout."); - } catch (ExecutionException e) { - throw new JuiceNetApiException(cmd.command + " from JuiceNet API execution issue."); - } - - return jsonResponse; - } -} diff --git a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/JuiceNetApiException.java b/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/JuiceNetApiException.java deleted file mode 100644 index 9bc4fd007c3..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/JuiceNetApiException.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2010-2025 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.juicenet.internal.api; - -import org.eclipse.jdt.annotation.NonNullByDefault; - -/** - * {@link JuiceNetApiException} implements an API Exception - * - * @author Jeff James - Initial contribution - */ -@NonNullByDefault -public class JuiceNetApiException extends Exception { - private static final long serialVersionUID = 5421236828224242152L; - - public JuiceNetApiException(String message) { - super(message); - } -} diff --git a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiCar.java b/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiCar.java deleted file mode 100644 index 5d4ec96f6e0..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiCar.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2010-2025 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.juicenet.internal.api.dto; - -import org.eclipse.jdt.annotation.NonNullByDefault; - -import com.google.gson.annotations.SerializedName; - -/** - * {@link JuiceNetApiCar } implements DTO for Car API call - * - * @author Jeff James - Initial contribution - */ -@NonNullByDefault -public class JuiceNetApiCar { - @SerializedName("car_id") - public int carId; - public String description = ""; - @SerializedName("battery_size_wh") - public int batterySizeWH; - @SerializedName("battery_range_m") - public int batteryRangeM; - @SerializedName("charging_rate_w") - public int chargingRateW; - @SerializedName("model_id") - public String modelId = ""; -} diff --git a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiDevice.java b/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiDevice.java deleted file mode 100644 index 33a36893806..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiDevice.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2010-2025 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.juicenet.internal.api.dto; - -import org.eclipse.jdt.annotation.NonNullByDefault; - -import com.google.gson.annotations.SerializedName; - -/** - * {@link JuiceNetApiDevice } implements DTO for Device Info API call - * - * @author Jeff James - Initial contribution - */ -@NonNullByDefault -public class JuiceNetApiDevice { - public String name = ""; - public String token = ""; - @SerializedName("unit_id") - public String unitId = ""; -} diff --git a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiDeviceChargingStatus.java b/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiDeviceChargingStatus.java deleted file mode 100644 index eb38542aeef..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiDeviceChargingStatus.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2010-2025 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.juicenet.internal.api.dto; - -import org.eclipse.jdt.annotation.NonNullByDefault; - -import com.google.gson.annotations.SerializedName; - -/** - * {@link JuiceNetApiDeviceChargingStatus } implements DTO for device charging status - * - * @author Jeff James - Initial contribution - */ -@NonNullByDefault -public class JuiceNetApiDeviceChargingStatus { - @SerializedName("amps_limit") - public int ampsLimit; - @SerializedName("amps_current") - public float ampsCurrent; - public int voltage; - @SerializedName("wh_energy") - public int whEnergy; - public int savings; - @SerializedName("watt_power") - public int wattPower; - @SerializedName("seconds_charging") - public int secondsCharging; - @SerializedName("wh_energy_at_plugin") - public int whEnergyAtPlugin; - @SerializedName("wh_energy_to_add") - public int whEnergyToAdd; - public int flags; -} diff --git a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiDeviceLifetimeStatus.java b/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiDeviceLifetimeStatus.java deleted file mode 100644 index 42ebf0606d1..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiDeviceLifetimeStatus.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2010-2025 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.juicenet.internal.api.dto; - -import org.eclipse.jdt.annotation.NonNullByDefault; - -import com.google.gson.annotations.SerializedName; - -/** - * {@link JuiceNetApiDeviceLifetimeStatus } implements DTO for Device Lifetime Status - * - * @author Jeff James - Initial contribution - */ -@NonNullByDefault -public class JuiceNetApiDeviceLifetimeStatus { - @SerializedName("wh_energy") - public int whEnergy; - public int savings; -} diff --git a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiDeviceStatus.java b/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiDeviceStatus.java deleted file mode 100644 index 63da975285a..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiDeviceStatus.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010-2025 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.juicenet.internal.api.dto; - -import org.eclipse.jdt.annotation.NonNullByDefault; - -import com.google.gson.annotations.SerializedName; - -/** - * {@link JuiceNetApiDeviceStatus } implements DTO for Device Status - * - * @author Jeff James - Initial contribution - */ -@NonNullByDefault -public class JuiceNetApiDeviceStatus { - @SerializedName("ID") - public String id = ""; - @SerializedName("info_timestamp") - public Long infoTimestamp = (long) 0; - @SerializedName("show_override") - public boolean showOverride; - public String state = ""; - public JuiceNetApiDeviceChargingStatus charging = new JuiceNetApiDeviceChargingStatus(); - public JuiceNetApiDeviceLifetimeStatus lifetime = new JuiceNetApiDeviceLifetimeStatus(); - @SerializedName("charging_time_left") - public int chargingTimeLeft; - @SerializedName("plug_unplug_time") - public Long plugUnplugTime = (long) 0; - @SerializedName("target_time") - public Long targetTime = (long) 0; - @SerializedName("unit_time") - public Long unitTime = (long) 0; - @SerializedName("utc_time") - public Long utcTime = (long) 0; - @SerializedName("default_target_time") - public long defaultTargetTime = 0; - @SerializedName("car_id") - public int carId; - public int temperature; - public String message = ""; -} diff --git a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiInfo.java b/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiInfo.java deleted file mode 100644 index 3fc798021dd..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiInfo.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2010-2025 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.juicenet.internal.api.dto; - -import org.eclipse.jdt.annotation.NonNullByDefault; - -import com.google.gson.annotations.SerializedName; - -/** - * {@link JuiceNetApiInfo } implements DTO for Info - * - * @author Jeff James - Initial contribution - */ -@NonNullByDefault -public class JuiceNetApiInfo { - public String name = ""; - public String address = ""; - public String city = ""; - public String zip = ""; - @SerializedName("country_code") - public String countryCode = ""; - public String ip = ""; - @SerializedName("gascost") - public int gasCost; - public int mpg; - public int ecost; - @SerializedName("whpermile") - public int whPerMile; - public String timeZoneId = ""; - @SerializedName("amps_wire_rating") - public int ampsWireRating; - @SerializedName("amps_unit_rating") - public int ampsUnitRating; - public JuiceNetApiCar[] cars = {}; -} diff --git a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiTouDay.java b/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiTouDay.java deleted file mode 100644 index 9cf4b87c8d8..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiTouDay.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2010-2025 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.juicenet.internal.api.dto; - -import org.eclipse.jdt.annotation.NonNullByDefault; - -import com.google.gson.annotations.SerializedName; - -/** - * {@link JuiceNetApiTouDay } implements DTO for TOU settings - * - * @author Jeff James - Initial contribution - */ -@NonNullByDefault -public class JuiceNetApiTouDay { - public int start; - public int end; - @SerializedName("car_ready_by") - public int carReadyBy; -} diff --git a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiTouSchedule.java b/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiTouSchedule.java deleted file mode 100644 index 36a4fc90e69..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/dto/JuiceNetApiTouSchedule.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2010-2025 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.juicenet.internal.api.dto; - -import org.eclipse.jdt.annotation.NonNullByDefault; - -/** - * {@link JuiceNetApiTouSchedule } implements DTO for TOU schedule - * - * @author Jeff James - Initial contribution - */ -@NonNullByDefault -public class JuiceNetApiTouSchedule { - public String type = ""; - public JuiceNetApiTouDay weekday = new JuiceNetApiTouDay(); - public JuiceNetApiTouDay weenend = new JuiceNetApiTouDay(); -} diff --git a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/config/JuiceNetBridgeConfiguration.java b/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/config/JuiceNetBridgeConfiguration.java deleted file mode 100644 index 1697bf5c133..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/config/JuiceNetBridgeConfiguration.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2010-2025 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.juicenet.internal.config; - -import org.eclipse.jdt.annotation.NonNullByDefault; - -/** - * The {@link JuiceNetBridgeConfiguration} class contains fields mapping thing configuration parameters. - * - * @author Jeff James - Initial contribution - */ -@NonNullByDefault -public class JuiceNetBridgeConfiguration { - public String apiToken = ""; - public int refreshInterval = 60; -} diff --git a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/discovery/JuiceNetDiscoveryService.java b/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/discovery/JuiceNetDiscoveryService.java deleted file mode 100644 index c90c15be858..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/discovery/JuiceNetDiscoveryService.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2010-2025 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.juicenet.internal.discovery; - -import static org.openhab.binding.juicenet.internal.JuiceNetBindingConstants.*; - -import java.util.Set; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.binding.juicenet.internal.handler.JuiceNetBridgeHandler; -import org.openhab.core.config.discovery.AbstractThingHandlerDiscoveryService; -import org.openhab.core.config.discovery.DiscoveryResult; -import org.openhab.core.config.discovery.DiscoveryResultBuilder; -import org.openhab.core.thing.ThingTypeUID; -import org.openhab.core.thing.ThingUID; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.ServiceScope; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * The {@link JuiceNetDiscoveryService} discovers all devices/zones reported by the FlumeTech Cloud. This requires the - * api - * key to get access to the cloud data. - * - * @author Jeff James - Initial contribution - */ -@Component(scope = ServiceScope.PROTOTYPE, service = JuiceNetDiscoveryService.class) -@NonNullByDefault -public class JuiceNetDiscoveryService extends AbstractThingHandlerDiscoveryService { - private final Logger logger = LoggerFactory.getLogger(JuiceNetDiscoveryService.class); - - private static final Set DISCOVERABLE_THING_TYPES_UIDS = Set.of(DEVICE_THING_TYPE); - - public JuiceNetDiscoveryService() { - super(JuiceNetBridgeHandler.class, DISCOVERABLE_THING_TYPES_UIDS, 0, false); - } - - @Override - protected synchronized void startScan() { - thingHandler.iterateApiDevices(); - } - - public void notifyDiscoveryDevice(String id, String name) { - ThingUID bridgeUID = thingHandler.getThing().getUID(); - - ThingUID uid = new ThingUID(DEVICE_THING_TYPE, bridgeUID, id); - - DiscoveryResult result = DiscoveryResultBuilder.create(uid).withBridge(bridgeUID) - .withProperty(PARAMETER_UNIT_ID, id).withLabel(name).build(); - thingDiscovered(result); - logger.debug("Discovered JuiceNetDevice {} - {}", uid, name); - } -} diff --git a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/handler/JuiceNetBridgeHandler.java b/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/handler/JuiceNetBridgeHandler.java deleted file mode 100644 index 962d2c232d8..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/handler/JuiceNetBridgeHandler.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (c) 2010-2025 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.juicenet.internal.handler; - -import static org.openhab.binding.juicenet.internal.JuiceNetBindingConstants.*; - -import java.util.Collection; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.jetty.client.HttpClient; -import org.openhab.binding.juicenet.internal.api.JuiceNetApi; -import org.openhab.binding.juicenet.internal.api.JuiceNetApiException; -import org.openhab.binding.juicenet.internal.api.dto.JuiceNetApiDevice; -import org.openhab.binding.juicenet.internal.config.JuiceNetBridgeConfiguration; -import org.openhab.binding.juicenet.internal.discovery.JuiceNetDiscoveryService; -import org.openhab.core.config.core.Configuration; -import org.openhab.core.thing.Bridge; -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.BaseBridgeHandler; -import org.openhab.core.thing.binding.ThingHandler; -import org.openhab.core.thing.binding.ThingHandlerService; -import org.openhab.core.types.Command; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * The {@link JuiceNetBridgeHandler} is responsible for handling commands, which are - * sent to one of the channels. - * - * @author Jeff James - Initial contribution - */ -@NonNullByDefault -public class JuiceNetBridgeHandler extends BaseBridgeHandler { - - private final Logger logger = LoggerFactory.getLogger(JuiceNetBridgeHandler.class); - - private JuiceNetBridgeConfiguration config = new JuiceNetBridgeConfiguration(); - private final JuiceNetApi api; - - public JuiceNetApi getApi() { - return api; - } - - private @Nullable ScheduledFuture pollingJob; - private @Nullable JuiceNetDiscoveryService discoveryService; - - public JuiceNetBridgeHandler(Bridge bridge, HttpClient httpClient) { - super(bridge); - - this.api = new JuiceNetApi(httpClient, getThing().getUID()); - } - - @Override - public void handleCommand(ChannelUID channelUID, Command command) { - } - - @Override - public void initialize() { - config = getConfigAs(JuiceNetBridgeConfiguration.class); - - logger.trace("Bridge initialized: {}", Objects.requireNonNull(getThing()).getUID()); - - api.setApiToken(config.apiToken); - - updateStatus(ThingStatus.UNKNOWN); - // Bridge will go online after the first successful API call in iterateApiDevices. iterateApiDevices will be - // called when a child device attempts to goOnline and needs to retrieve the api token - - pollingJob = scheduler.scheduleWithFixedDelay(this::pollDevices, 10, config.refreshInterval, TimeUnit.SECONDS); - - // Call here in order to discover any devices. - iterateApiDevices(); - } - - @Override - public void dispose() { - logger.debug("Handler disposed."); - ScheduledFuture pollingJob = this.pollingJob; - if (pollingJob != null) { - pollingJob.cancel(true); - this.pollingJob = null; - } - } - - public void setDiscoveryService(JuiceNetDiscoveryService discoveryService) { - this.discoveryService = discoveryService; - } - - @Override - public void childHandlerInitialized(ThingHandler childHandler, Thing childThing) { - // Call here to set the Api Token for any newly initialized Child devices - iterateApiDevices(); - } - - /** - * Get the services registered for this bridge. Provides the discovery service. - */ - @Override - public Collection> getServices() { - return Set.of(JuiceNetDiscoveryService.class); - } - - public void handleApiException(Exception e) { - if (e instanceof JuiceNetApiException) { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, e.toString()); - } else if (e instanceof InterruptedException) { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, e.toString()); - Thread.currentThread().interrupt(); - } else { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.NONE, e.toString()); - } - } - - @Nullable - public Thing getThingById(String id) { - List childThings = getThing().getThings(); - - for (Thing childThing : childThings) { - Configuration configuration = childThing.getConfiguration(); - - String childId = configuration.get(PARAMETER_UNIT_ID).toString(); - - if (childId.equals(id)) { - return childThing; - } - } - - return null; - } - - // This function will query the list of devices from the API and then set the name/token in the child handlers. If a - // child does not exist, it will notify the Discovery service. If it is successful, it will ensure the bridge status - // is updated - // to ONLINE. - public void iterateApiDevices() { - List listDevices; - - try { - listDevices = api.queryDeviceList(); - } catch (JuiceNetApiException | InterruptedException e) { - handleApiException(e); - return; - } - - if (getThing().getStatus() != ThingStatus.ONLINE) { - updateStatus(ThingStatus.ONLINE); - } - - JuiceNetDiscoveryService discoveryService = this.discoveryService; - for (JuiceNetApiDevice dev : listDevices) { - Thing childThing = getThingById(dev.unitId); - if (childThing == null) { - if (discoveryService != null) { - discoveryService.notifyDiscoveryDevice(dev.unitId, dev.name); - } - } else { - JuiceNetDeviceHandler childHandler = (JuiceNetDeviceHandler) childThing.getHandler(); - if (childHandler != null) { - childHandler.setNameAndToken(dev.name, dev.token); - } - } - } - } - - private void pollDevices() { - List things = getThing().getThings(); - - for (Thing t : things) { - if (!t.getThingTypeUID().equals(DEVICE_THING_TYPE)) { - continue; - } - - JuiceNetDeviceHandler handler = (JuiceNetDeviceHandler) t.getHandler(); - if (handler == null) { - logger.trace("no handler for thing: {}", t.getUID()); - continue; - } - - handler.queryDeviceStatusAndInfo(); - } - } -} diff --git a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/handler/JuiceNetDeviceHandler.java b/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/handler/JuiceNetDeviceHandler.java deleted file mode 100644 index 4152ad147ff..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/handler/JuiceNetDeviceHandler.java +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright (c) 2010-2025 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.juicenet.internal.handler; - -import static org.openhab.binding.juicenet.internal.JuiceNetBindingConstants.*; - -import java.time.Instant; -import java.time.ZoneId; -import java.time.ZonedDateTime; -import java.time.temporal.ChronoField; -import java.util.Objects; -import java.util.concurrent.TimeUnit; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.openhab.binding.juicenet.internal.api.JuiceNetApi; -import org.openhab.binding.juicenet.internal.api.JuiceNetApiException; -import org.openhab.binding.juicenet.internal.api.dto.JuiceNetApiCar; -import org.openhab.binding.juicenet.internal.api.dto.JuiceNetApiDeviceStatus; -import org.openhab.binding.juicenet.internal.api.dto.JuiceNetApiInfo; -import org.openhab.binding.juicenet.internal.api.dto.JuiceNetApiTouSchedule; -import org.openhab.core.config.core.Configuration; -import org.openhab.core.library.types.DateTimeType; -import org.openhab.core.library.types.DecimalType; -import org.openhab.core.library.types.OnOffType; -import org.openhab.core.library.types.QuantityType; -import org.openhab.core.library.types.StringType; -import org.openhab.core.library.unit.ImperialUnits; -import org.openhab.core.library.unit.SIUnits; -import org.openhab.core.library.unit.Units; -import org.openhab.core.thing.Bridge; -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.BridgeHandler; -import org.openhab.core.types.Command; -import org.openhab.core.types.RefreshType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * The {@link JuiceNetDeviceHandler} is responsible for handling commands, which are - * sent to one of the channels. - * - * @author Jeff James - Initial contribution - */ -@NonNullByDefault -public class JuiceNetDeviceHandler extends BaseThingHandler { - - private final Logger logger = LoggerFactory.getLogger(JuiceNetDeviceHandler.class); - - // properties - private String name = ""; - - private String token = ""; - private long targetTimeTou = 0; - private long lastInfoTimestamp = 0; - - JuiceNetApiDeviceStatus deviceStatus = new JuiceNetApiDeviceStatus(); - JuiceNetApiInfo deviceInfo = new JuiceNetApiInfo(); - JuiceNetApiTouSchedule deviceTouSchedule = new JuiceNetApiTouSchedule(); - JuiceNetApiCar deviceCar = new JuiceNetApiCar(); - - public JuiceNetDeviceHandler(Thing thing) { - super(thing); - } - - public void setNameAndToken(String name, String token) { - logger.trace("setNameAndToken"); - this.token = token; - - if (!name.equals(this.name)) { - updateProperty(PROPERTY_NAME, name); - this.name = name; - } - - if (getThing().getStatus() != ThingStatus.ONLINE) { - goOnline(); - } - } - - @Override - public void initialize() { - logger.trace("Device initialized: {}", Objects.requireNonNull(getThing().getUID())); - Configuration configuration = getThing().getConfiguration(); - - String stringId = configuration.get(PARAMETER_UNIT_ID).toString(); - if (stringId.isEmpty()) { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR, - "@text/offline.configuration-error.id-missing"); - return; - } - - updateStatus(ThingStatus.UNKNOWN); - - // This device will go ONLINE on the first successful API call in queryDeviceStatusAndInfo - } - - private void handleApiException(Exception e) { - if (e instanceof JuiceNetApiException) { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, e.toString()); - } else if (e instanceof InterruptedException) { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, e.toString()); - Thread.currentThread().interrupt(); - } else { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.NONE, e.toString()); - } - } - - private void goOnline() { - logger.trace("goOnline"); - if (this.getThing().getStatus() == ThingStatus.ONLINE) { - return; - } - - if (token.isEmpty()) { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR, - "@text/offline.configuration-error.non-existent-device"); - return; - } - - try { - tryQueryDeviceStatusAndInfo(); - } catch (JuiceNetApiException | InterruptedException e) { - handleApiException(e); - return; - } - - updateStatus(ThingStatus.ONLINE); - } - - @Nullable - private JuiceNetApi getApi() { - Bridge bridge = getBridge(); - if (bridge == null) { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR, - "@text/offline.configuration-error.bridge-missing"); - return null; - } - BridgeHandler handler = Objects.requireNonNull(bridge.getHandler()); - - return ((JuiceNetBridgeHandler) handler).getApi(); - } - - @Override - public void handleCommand(ChannelUID channelUID, Command command) { - JuiceNetApi api = getApi(); - if (api == null) { - return; - } - - if (command instanceof RefreshType) { - switch (channelUID.getId()) { - case CHANNEL_NAME: - case CHANNEL_STATE: - case CHANNEL_MESSAGE: - case CHANNEL_OVERRIDE: - case CHANNEL_CHARGING_TIME_LEFT: - case CHANNEL_PLUG_UNPLUG_TIME: - case CHANNEL_TARGET_TIME: - case CHANNEL_UNIT_TIME: - case CHANNEL_TEMPERATURE: - case CHANNEL_CURRENT_LIMIT: - case CHANNEL_CURRENT: - case CHANNEL_VOLTAGE: - case CHANNEL_ENERGY: - case CHANNEL_SAVINGS: - case CHANNEL_POWER: - case CHANNEL_CHARGING_TIME: - case CHANNEL_ENERGY_AT_PLUGIN: - case CHANNEL_ENERGY_TO_ADD: - case CHANNEL_LIFETIME_ENERGY: - case CHANNEL_LIFETIME_SAVINGS: - case CHANNEL_CAR_DESCRIPTION: - case CHANNEL_CAR_BATTERY_SIZE: - case CHANNEL_CAR_BATTERY_RANGE: - case CHANNEL_CAR_CHARGING_RATE: - refreshStatusChannels(); - break; - case CHANNEL_GAS_COST: - case CHANNEL_FUEL_CONSUMPTION: - case CHANNEL_ECOST: - case CHANNEL_ENERGY_PER_MILE: - refreshInfoChannels(); - break; - } - - return; - } - - try { - switch (channelUID.getId()) { - case CHANNEL_CURRENT_LIMIT: - int limit = ((QuantityType) command).intValue(); - api.setCurrentLimit(Objects.requireNonNull(token), limit); - break; - case CHANNEL_TARGET_TIME: { - int energyAtPlugin = 0; - int energyToAdd = deviceCar.batterySizeWH; - - if (!(command instanceof DateTimeType)) { - logger.info("Target Time is not an instance of DateTimeType"); - return; - } - - ZonedDateTime datetime = ((DateTimeType) command).getZonedDateTime(ZoneId.systemDefault()); - Long targetTime = datetime.toEpochSecond() + datetime.get(ChronoField.OFFSET_SECONDS); - logger.debug("DateTime: {} - {}", datetime.toString(), targetTime); - - api.setOverride(Objects.requireNonNull(token), energyAtPlugin, targetTime, energyToAdd); - - break; - } - case CHANNEL_CHARGING_STATE: { - String state = ((StringType) command).toString(); - Long overrideTime = deviceStatus.unitTime; - int energyAtPlugin = 0; - int energyToAdd = deviceCar.batterySizeWH; - - switch (state) { - case "stop": - if (targetTimeTou == 0) { - targetTimeTou = deviceStatus.targetTime; - } - overrideTime = deviceStatus.unitTime + 31556926; - break; - case "start": - if (targetTimeTou == 0) { - targetTimeTou = deviceStatus.targetTime; - } - overrideTime = deviceStatus.unitTime; - break; - case "smart": - overrideTime = deviceStatus.defaultTargetTime; - break; - } - - api.setOverride(Objects.requireNonNull(token), energyAtPlugin, overrideTime, energyToAdd); - - break; - } - case CHANNEL_OVERRIDE: { - if (command instanceof OnOffType onOffCommand && OnOffType.OFF.equals(onOffCommand)) { - api.setOverride(Objects.requireNonNull(token), 0, ((long) 0), 0); - } - - break; - } - } - } catch (JuiceNetApiException | InterruptedException e) { - handleApiException(e); - return; - } - } - - private void tryQueryDeviceStatusAndInfo() throws JuiceNetApiException, InterruptedException { - String apiToken = Objects.requireNonNull(this.token); - JuiceNetApi api = getApi(); - if (api == null) { - return; - } - - deviceStatus = api.queryDeviceStatus(apiToken); - - if (deviceStatus.infoTimestamp > lastInfoTimestamp) { - lastInfoTimestamp = deviceStatus.infoTimestamp; - - deviceInfo = api.queryInfo(apiToken); - deviceTouSchedule = api.queryTOUSchedule(apiToken); - refreshInfoChannels(); - } - - int carId = deviceStatus.carId; - for (JuiceNetApiCar car : deviceInfo.cars) { - if (car.carId == carId) { - this.deviceCar = car; - break; - } - } - - refreshStatusChannels(); - } - - public void queryDeviceStatusAndInfo() { - logger.trace("queryStatusAndInfo"); - ThingStatus status = getThing().getStatus(); - - if (status != ThingStatus.ONLINE) { - goOnline(); - return; - } - - try { - tryQueryDeviceStatusAndInfo(); - } catch (JuiceNetApiException | InterruptedException e) { - handleApiException(e); - return; - } - } - - private void refreshStatusChannels() { - updateState(CHANNEL_STATE, new StringType(deviceStatus.state)); - - if (deviceStatus.targetTime <= deviceStatus.unitTime) { - updateState(CHANNEL_CHARGING_STATE, new StringType("start")); - } else if ((deviceStatus.targetTime - deviceStatus.unitTime) < TimeUnit.DAYS.toSeconds(2)) { - updateState(CHANNEL_CHARGING_STATE, new StringType("smart")); - } else { - updateState(CHANNEL_CHARGING_STATE, new StringType("stop")); - } - - updateState(CHANNEL_MESSAGE, new StringType(deviceStatus.message)); - updateState(CHANNEL_OVERRIDE, OnOffType.from(deviceStatus.showOverride)); - updateState(CHANNEL_CHARGING_TIME_LEFT, new QuantityType<>(deviceStatus.chargingTimeLeft, Units.SECOND)); - updateState(CHANNEL_PLUG_UNPLUG_TIME, new DateTimeType(Instant.ofEpochSecond(deviceStatus.plugUnplugTime))); - updateState(CHANNEL_TARGET_TIME, new DateTimeType(Instant.ofEpochSecond(deviceStatus.targetTime))); - updateState(CHANNEL_UNIT_TIME, new DateTimeType(Instant.ofEpochSecond(deviceStatus.utcTime))); - updateState(CHANNEL_TEMPERATURE, new QuantityType<>(deviceStatus.temperature, SIUnits.CELSIUS)); - updateState(CHANNEL_CURRENT_LIMIT, new QuantityType<>(deviceStatus.charging.ampsLimit, Units.AMPERE)); - updateState(CHANNEL_CURRENT, new QuantityType<>(deviceStatus.charging.ampsCurrent, Units.AMPERE)); - updateState(CHANNEL_VOLTAGE, new QuantityType<>(deviceStatus.charging.voltage, Units.VOLT)); - updateState(CHANNEL_ENERGY, new QuantityType<>(deviceStatus.charging.whEnergy, Units.WATT_HOUR)); - updateState(CHANNEL_SAVINGS, new DecimalType(deviceStatus.charging.savings / 100.0)); - updateState(CHANNEL_POWER, new QuantityType<>(deviceStatus.charging.wattPower, Units.WATT)); - updateState(CHANNEL_CHARGING_TIME, new QuantityType<>(deviceStatus.charging.secondsCharging, Units.SECOND)); - updateState(CHANNEL_ENERGY_AT_PLUGIN, - new QuantityType<>(deviceStatus.charging.whEnergyAtPlugin, Units.WATT_HOUR)); - updateState(CHANNEL_ENERGY_TO_ADD, new QuantityType<>(deviceStatus.charging.whEnergyToAdd, Units.WATT_HOUR)); - updateState(CHANNEL_LIFETIME_ENERGY, new QuantityType<>(deviceStatus.lifetime.whEnergy, Units.WATT_HOUR)); - updateState(CHANNEL_LIFETIME_SAVINGS, new DecimalType(deviceStatus.lifetime.savings / 100.0)); - - // update Car items - updateState(CHANNEL_CAR_DESCRIPTION, new StringType(deviceCar.description)); - updateState(CHANNEL_CAR_BATTERY_SIZE, new QuantityType<>(deviceCar.batterySizeWH, Units.WATT_HOUR)); - updateState(CHANNEL_CAR_BATTERY_RANGE, new QuantityType<>(deviceCar.batteryRangeM, ImperialUnits.MILE)); - updateState(CHANNEL_CAR_CHARGING_RATE, new QuantityType<>(deviceCar.chargingRateW, Units.WATT)); - } - - private void refreshInfoChannels() { - updateState(CHANNEL_NAME, new StringType(name)); - updateState(CHANNEL_GAS_COST, new DecimalType(deviceInfo.gasCost / 100.0)); - // currently there is no unit defined for fuel consumption - updateState(CHANNEL_FUEL_CONSUMPTION, new DecimalType(deviceInfo.mpg)); - updateState(CHANNEL_ECOST, new DecimalType(deviceInfo.ecost / 100.0)); - updateState(CHANNEL_ENERGY_PER_MILE, new DecimalType(deviceInfo.whPerMile)); - } -} diff --git a/bundles/org.openhab.binding.juicenet/src/main/resources/OH-INF/addon/addon.xml b/bundles/org.openhab.binding.juicenet/src/main/resources/OH-INF/addon/addon.xml deleted file mode 100644 index cd2b7e91e41..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/resources/OH-INF/addon/addon.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - binding - JuiceNet Binding - This is the binding supporting the JuiceNet EV charger. - local - - diff --git a/bundles/org.openhab.binding.juicenet/src/main/resources/OH-INF/i18n/juicenet.properties b/bundles/org.openhab.binding.juicenet/src/main/resources/OH-INF/i18n/juicenet.properties deleted file mode 100644 index 31fe45e2494..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/resources/OH-INF/i18n/juicenet.properties +++ /dev/null @@ -1,98 +0,0 @@ -# add-on - -addon.juicenet.name = JuiceNet Binding -addon.juicenet.description = This is the binding supporting the JuiceNet EV charger. - -# thing types - -thing-type.juicenet.account.label = JuiceNet Account -thing-type.juicenet.account.description = This is the account for which your device(s) are registered at home.juice.net. -thing-type.juicenet.device.label = JuiceBox Charger -thing-type.juicenet.device.description = JuiceBox EV Charger - -# thing types config - -thing-type.config.juicenet.account.apiToken.label = API Token -thing-type.config.juicenet.account.apiToken.description = API Token from the user profile page. (https://home.juice.net/Manage) -thing-type.config.juicenet.account.refreshInterval.label = Refresh Interval -thing-type.config.juicenet.account.refreshInterval.description = Interval the device is polled in seconds. -thing-type.config.juicenet.device.unitID.label = Unit ID -thing-type.config.juicenet.device.unitID.description = EV charger Unit ID from the JuiceNet webpage. (https://home.juice.net) - -# channel types - -channel-type.juicenet.carBatteryRange.label = Mileage Range -channel-type.juicenet.carBatteryRange.description = Car distance range. -channel-type.juicenet.carBatterySize.label = Car Battery Pack Size -channel-type.juicenet.carBatterySize.description = Car battery pack size. -channel-type.juicenet.carChargingRate.label = Car Charging Rate -channel-type.juicenet.carChargingRate.description = Car charging rate. -channel-type.juicenet.carDescription.label = Car Description -channel-type.juicenet.carDescription.description = Car description of vehicle currently or last charged. -channel-type.juicenet.chargingState.label = Charging State -channel-type.juicenet.chargingState.description = The charging state (Start Charging, Smart Charging, Stop Charging). -channel-type.juicenet.chargingState.state.option.start = Start Charging -channel-type.juicenet.chargingState.state.option.smart = Smart Charging -channel-type.juicenet.chargingState.state.option.stop = Stop Charging -channel-type.juicenet.chargingTime.label = Charging Time -channel-type.juicenet.chargingTime.description = Charging time since plug-in time. -channel-type.juicenet.chargingTimeLeft.label = Charging Time Left -channel-type.juicenet.chargingTimeLeft.description = Charging time left. -channel-type.juicenet.current.label = Current -channel-type.juicenet.current.description = Current charging current. -channel-type.juicenet.currentLimit.label = Current Limit -channel-type.juicenet.currentLimit.description = Max charging current allowed. -channel-type.juicenet.ecost.label = Utility Energy Cost -channel-type.juicenet.ecost.description = Cost of electricity from utility company. (currency / kWh) -channel-type.juicenet.energy.label = Current Energy -channel-type.juicenet.energy.description = Current power level of vehicle. -channel-type.juicenet.energyAtPlugin.label = Energy at Plugin -channel-type.juicenet.energyAtPlugin.description = Energy value at the plugging time. -channel-type.juicenet.energyPerMile.label = Energy Hours Per Mile -channel-type.juicenet.energyPerMile.description = Energy Hours Per Mile. -channel-type.juicenet.energyToAdd.label = Energy to Add -channel-type.juicenet.energyToAdd.description = Amount of energy to be added in current session. -channel-type.juicenet.fuelConsumption.label = Fuel consumption -channel-type.juicenet.fuelConsumption.description = Distance per volume (mpg) used in savings calculations. -channel-type.juicenet.gasCost.label = Gas Cost -channel-type.juicenet.gasCost.description = Cost of gasoline used in savings calculations. -channel-type.juicenet.lifetimeEnergy.label = Lifetime Energy -channel-type.juicenet.lifetimeEnergy.description = Total energy delivered to vehicles during lifetime. -channel-type.juicenet.lifetimeSavings.label = Lifetime Savings -channel-type.juicenet.lifetimeSavings.description = EV driving saving during lifetime. -channel-type.juicenet.message.label = State Message -channel-type.juicenet.message.description = This is a message detailing the state of the EV charger. -channel-type.juicenet.name.label = Name -channel-type.juicenet.name.description = Juice Box name. -channel-type.juicenet.override.label = Override State -channel-type.juicenet.override.description = Smart charging is overridden. -channel-type.juicenet.plugUnplugTime.label = Plug/Unplug Time -channel-type.juicenet.plugUnplugTime.description = Last time of either plug-in or plug-out. -channel-type.juicenet.plugUnplugTime.state.pattern = %1$tB %1$te, %1$tY %1$tl:%1$tM %1$tp -channel-type.juicenet.power.label = Charging Power -channel-type.juicenet.power.description = Current charging power. -channel-type.juicenet.savings.label = Savings -channel-type.juicenet.savings.description = Current session EV savings. -channel-type.juicenet.state.label = Device State -channel-type.juicenet.state.description = This is the current device state (Available, Plugged-In, Charging, Error, Disconnected). -channel-type.juicenet.state.state.option.standby = Available -channel-type.juicenet.state.state.option.plugged = Plugged-In -channel-type.juicenet.state.state.option.charging = Charging -channel-type.juicenet.state.state.option.error = Error -channel-type.juicenet.state.state.option.disconnect = Disconnected -channel-type.juicenet.targetTime.label = Target Time -channel-type.juicenet.targetTime.description = “Start charging” start time, or time to start when overriding smart charging. -channel-type.juicenet.targetTime.state.pattern = %1$tB %1$te, %1$tY %1$tl:%1$tM %1$tp -channel-type.juicenet.temperature.label = Temperature -channel-type.juicenet.temperature.description = Current temperature at the unit. -channel-type.juicenet.unitTime.label = Unit Time -channel-type.juicenet.unitTime.description = Current time on the unit. -channel-type.juicenet.unitTime.state.pattern = %1$tB %1$te, %1$tY %1$tl:%1$tM %1$tp -channel-type.juicenet.voltage.label = Voltage -channel-type.juicenet.voltage.description = Current voltage. - -# offline configuration errors - -offline.configuration-error.id-missing = Must include an id in the configuration for the device. -offline.configuration-error.non-existent-device = Device does not exist as part of this JuiceNet Account -offline.configuration-error.bridge-missing = The JuiceBox device must be associated with a JuiceNet Account bridge diff --git a/bundles/org.openhab.binding.juicenet/src/main/resources/OH-INF/i18n/juicenet_it.properties b/bundles/org.openhab.binding.juicenet/src/main/resources/OH-INF/i18n/juicenet_it.properties deleted file mode 100644 index 156f8297428..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/resources/OH-INF/i18n/juicenet_it.properties +++ /dev/null @@ -1,98 +0,0 @@ -# add-on - -addon.juicenet.name = Binding JuiceNet -addon.juicenet.description = Questo è il gestore che supporta il caricabatterie JuiceNet EV. - -# thing types - -thing-type.juicenet.account.label = Iscrizione JuiceNet -thing-type.juicenet.account.description = Questo è l'iscrizione per il quale i tuoi dispositivi sono registrati su home.juice.net. -thing-type.juicenet.device.label = Caricabatterie JuiceBox -thing-type.juicenet.device.description = Caricabatterie JuiceBox EV - -# thing types config - -thing-type.config.juicenet.account.apiToken.label = Chiave API -thing-type.config.juicenet.account.apiToken.description = Chiave API dalla pagina del profilo utente (https\://home.juice.net/Manage) -thing-type.config.juicenet.account.refreshInterval.label = Intervallo di aggiornamento -thing-type.config.juicenet.account.refreshInterval.description = Intervallo di tempo delle interrogazioni al dispositivo, in secondi. -thing-type.config.juicenet.device.unitID.label = ID unità -thing-type.config.juicenet.device.unitID.description = ID dell'unità caricabatterie EV dalla pagina web JuiceNet. (https\://home.juice.net) - -# channel types - -channel-type.juicenet.carBatteryRange.label = Distanza percorribile -channel-type.juicenet.carBatteryRange.description = Massima distanza percorribile dall'automobile. -channel-type.juicenet.carBatterySize.label = Dimensione pacco batteria auto -channel-type.juicenet.carBatterySize.description = Dimensione pacco batteria auto. -channel-type.juicenet.carChargingRate.label = Tariffa ricarica auto -channel-type.juicenet.carChargingRate.description = Tariffa ricarica auto. -channel-type.juicenet.carDescription.label = Descrizione auto -channel-type.juicenet.carDescription.description = Descrizione del veicolo attualmente in carica o dell'ultimo in carica. -channel-type.juicenet.chargingState.label = Stato ricarica -channel-type.juicenet.chargingState.description = Stato della ricarica (Ricarica iniziata, Ricarica intelligente, Ricarica completata). -channel-type.juicenet.chargingState.state.option.start = Ricarica iniziata -channel-type.juicenet.chargingState.state.option.smart = Ricarica intelligente -channel-type.juicenet.chargingState.state.option.stop = Ricarica completata -channel-type.juicenet.chargingTime.label = Tempo di ricarica -channel-type.juicenet.chargingTime.description = Tempo di ricarica dall'inizio. -channel-type.juicenet.chargingTimeLeft.label = Tempo di ricarica rimasto -channel-type.juicenet.chargingTimeLeft.description = Tempo di ricarica rimasto. -channel-type.juicenet.current.label = Corrente -channel-type.juicenet.current.description = Corrente di ricarica. -channel-type.juicenet.currentLimit.label = Limite corrente -channel-type.juicenet.currentLimit.description = Corrente di ricarica massima consentita. -channel-type.juicenet.ecost.label = Costo energia rivenditore -channel-type.juicenet.ecost.description = Costo dell'energia elettrica dal rivenditore (valuta / kWh) -channel-type.juicenet.energy.label = Livello potenza attuale -channel-type.juicenet.energy.description = Livello di potenza attuale del veicolo. -channel-type.juicenet.energyAtPlugin.label = Livello di potenza all'avvio -channel-type.juicenet.energyAtPlugin.description = Livello di potenza al momento dell'avvio. -channel-type.juicenet.energyPerMile.label = Ore di energia per miglia -channel-type.juicenet.energyPerMile.description = Ore di energia per miglia. -channel-type.juicenet.energyToAdd.label = Energia da caricare -channel-type.juicenet.energyToAdd.description = Quantità di energia da caricare durante la sessione corrente. -channel-type.juicenet.fuelConsumption.label = Consumo di carburante -channel-type.juicenet.fuelConsumption.description = Distanza per volume (mpg) utilizzata nei calcoli di risparmio energetico. -channel-type.juicenet.gasCost.label = Costo della benzina -channel-type.juicenet.gasCost.description = Costo della benzina utilizzata nei calcoli di risparmio energetico. -channel-type.juicenet.lifetimeEnergy.label = Energia totale -channel-type.juicenet.lifetimeEnergy.description = Energia totale fornita al veicolo durante la sua vita. -channel-type.juicenet.lifetimeSavings.label = Risparmio globale -channel-type.juicenet.lifetimeSavings.description = Risparmio ottenuto grazie alla "guida EV" durante l'intera la vita del veicolo. -channel-type.juicenet.message.label = Messaggio di stato -channel-type.juicenet.message.description = Questo è un messaggio che descrive lo stato del caricabatterie EV. -channel-type.juicenet.name.label = Nome -channel-type.juicenet.name.description = Nome Juice box. -channel-type.juicenet.override.label = Stato sovrascrittura -channel-type.juicenet.override.description = La ricarica intelligente è ignorata. -channel-type.juicenet.plugUnplugTime.label = Tempo Inizio/Scollegamento -channel-type.juicenet.plugUnplugTime.description = La durata dell'ultima carica, dall'inizio allo sollegamento. -channel-type.juicenet.plugUnplugTime.state.pattern = %1$tB %1$te, %1$tY %1$tl\:%1$tM %1$tp -channel-type.juicenet.power.label = Potenza di ricarica -channel-type.juicenet.power.description = Potenza di ricarica attuale. -channel-type.juicenet.savings.label = Risparmio -channel-type.juicenet.savings.description = Il risparmio EV ottenuto con la sessione corrente. -channel-type.juicenet.state.label = Stato del dispositivo -channel-type.juicenet.state.description = Stato attuale del dispositivo (Disponibile, Connesso, In carica, Errore, Disconnesso). -channel-type.juicenet.state.state.option.standby = Disponibile -channel-type.juicenet.state.state.option.plugged = Connesso -channel-type.juicenet.state.state.option.charging = In carica -channel-type.juicenet.state.state.option.error = Errore -channel-type.juicenet.state.state.option.disconnect = Disconnesso -channel-type.juicenet.targetTime.label = Orario obiettivo -channel-type.juicenet.targetTime.description = “Inizia la ricarica”\: ora d'inizio o ora d'inizio della sovrascrittura della ricarica intelligente. -channel-type.juicenet.targetTime.state.pattern = %1$tB %1$te, %1$tY %1$tl\:%1$tM %1$tp -channel-type.juicenet.temperature.label = Temperatura -channel-type.juicenet.temperature.description = Temperatura corrente dell'unità. -channel-type.juicenet.unitTime.label = Orario dell'unità -channel-type.juicenet.unitTime.description = Orario attuale dell'unità. -channel-type.juicenet.unitTime.state.pattern = %1$tB %1$te, %1$tY %1$tl\:%1$tM %1$tp -channel-type.juicenet.voltage.label = Tensione -channel-type.juicenet.voltage.description = Tensione attuale. - -# offline configuration errors - -offline.configuration-error.id-missing = Deve includere un Identificativo nella configurazione del dispositivo. -offline.configuration-error.non-existent-device = Il dispositivo non esiste come parte di questa registrazione JuiceNet -offline.configuration-error.bridge-missing = Il dispositivo JuiceBox deve essere associato a una registrazione "ponte" JuiceNet diff --git a/bundles/org.openhab.binding.juicenet/src/main/resources/OH-INF/thing/juicenet-account.xml b/bundles/org.openhab.binding.juicenet/src/main/resources/OH-INF/thing/juicenet-account.xml deleted file mode 100644 index 40e76cf361d..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/resources/OH-INF/thing/juicenet-account.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - This is the account for which your device(s) are registered at home.juice.net. - - - - - API Token from the user profile page. (https://home.juice.net/Manage) - - - - Interval the device is polled in seconds. - 60 - - - - diff --git a/bundles/org.openhab.binding.juicenet/src/main/resources/OH-INF/thing/juicenet-device.xml b/bundles/org.openhab.binding.juicenet/src/main/resources/OH-INF/thing/juicenet-device.xml deleted file mode 100644 index e1249391953..00000000000 --- a/bundles/org.openhab.binding.juicenet/src/main/resources/OH-INF/thing/juicenet-device.xml +++ /dev/null @@ -1,288 +0,0 @@ - - - - - - - - - - JuiceBox EV Charger - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - unitID - - - - - EV charger Unit ID from the JuiceNet webpage. (https://home.juice.net) - - - - - - String - - Juice Box name. - - - - - String - - The charging state (Start Charging, Smart Charging, Stop Charging). - - - - - - - - recommend - - - - String - - This is the current device state (Available, Plugged-In, Charging, Error, Disconnected). - - - - - - - - - - - - - String - - This is a message detailing the state of the EV charger. - - - - - Switch - - Smart charging is overridden. - - - - - Number:Time - - Charging time left. - Time - - - - - DateTime - - Last time of either plug-in or plug-out. - Time - - - - - DateTime - - “Start charging” start time, or time to start when overriding smart charging. - Time - - - - - DateTime - - Current time on the unit. - Time - - - - - Number:Temperature - - Current temperature at the unit. - Temperature - - - - - Number:ElectricCurrent - - Max charging current allowed. - - - - - Number:ElectricCurrent - - Current charging current. - - - - - Number:ElectricPotential - - Current voltage. - - - - - Number:Energy - - Current power level of vehicle. - - - - - Number - - Current session EV savings. - - - - - Number:Power - - Current charging power. - - - - - Number:Time - - Charging time since plug-in time. - Time - - - - - Number:Energy - - Energy value at the plugging time. - - - - - Number:Energy - - Amount of energy to be added in current session. - - - - - Number:Energy - - Total energy delivered to vehicles during lifetime. - - - - - Number - - EV driving saving during lifetime. - - - - - Number - - Cost of gasoline used in savings calculations. - - - - - Number - - Distance per volume (mpg) used in savings calculations. - - - - - Number - - Cost of electricity from utility company. (currency / kWh) - - - - - Number:Power - - Energy Hours Per Mile. - - - - - String - - Car description of vehicle currently or last charged. - - - - - Number:Energy - - Car battery pack size. - - - - - Number:Length - - Car distance range. - - - - - Number:Power - - Car charging rate. - - - - diff --git a/bundles/pom.xml b/bundles/pom.xml index 2cb3218ffd6..af78d0858f8 100644 --- a/bundles/pom.xml +++ b/bundles/pom.xml @@ -216,7 +216,6 @@ org.openhab.binding.jablotron org.openhab.binding.jeelink org.openhab.binding.jellyfin - org.openhab.binding.juicenet org.openhab.binding.kaleidescape org.openhab.binding.keba org.openhab.binding.km200