Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[renault] Initial Contribution #11467

Merged
merged 16 commits into from
Dec 5, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions bundles/org.openhab.binding.renault/NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
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
45 changes: 45 additions & 0 deletions bundles/org.openhab.binding.renault/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Renault Binding

This binding allow MyRenault App. users to get battery status and other data from their cars.

A binding that translates the [python based renault-api](https://renault-api.readthedocs.io/en/latest/) in an easy to use binding.


## Supported Things

Works on my car (Renault Zoe 50) but I only have one car to test.


## Discovery

No discovery

## Binding Configuration

You require your MyRenault credential, locale and VIN for your MyRenault registered car.
lolodomo marked this conversation as resolved.
Show resolved Hide resolved

## Thing Configuration

The thing has these configuration parameters:

| Parameter | Description | Required |
|-------------------|----------------------------------------|----------|
| myRenaultUsername | MyRenault Username. | yes |
| myRenaultPassword | MyRenault Password. | yes |
| locale | MyRenault Location (language_country). | yes |
| vin | Vehicle Identification Number. | yes |
| refreshInterval | Interval the car is polled in minutes. | yes |
lolodomo marked this conversation as resolved.
Show resolved Hide resolved

## Channels

Currently all available channels are read only:

| Channel ID | Type | Description |
|--------------|----------|---------------------------------|
| batterylevel | Number | State of the battery in % |
| hvacstatus | Switch | HVAC status switch |
| image | String | Image URL of MyRenault |
| location | Location | The GPS position of the vehicle |
| odometer | Number | Total distance travelled |
lolodomo marked this conversation as resolved.
Show resolved Hide resolved


17 changes: 17 additions & 0 deletions bundles/org.openhab.binding.renault/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
<version>3.2.0-SNAPSHOT</version>
</parent>

<artifactId>org.openhab.binding.renault</artifactId>

<name>openHAB Add-ons :: Bundles :: Renault Binding</name>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<features name="org.openhab.binding.renault-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>

<feature name="openhab-binding-renault" description="Renault Binding" version="${project.version}">
<feature>openhab-runtime-base</feature>
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.renault/${project.version}</bundle>
</feature>
</features>
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Copyright (c) 2010-2021 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.renault.internal;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.thing.ThingTypeUID;

/**
* The {@link RenaultBindingConstants} class defines common constants, which are
* used across the whole binding.
*
* @author Doug Culnane - Initial contribution
*/
@NonNullByDefault
public class RenaultBindingConstants {

private static final String BINDING_ID = "renault";

// List of all Thing Type UIDs
public static final ThingTypeUID THING_TYPE_CAR = new ThingTypeUID(BINDING_ID, "car");

// List of all Channel ids
public static final String CHANNEL_BATTERY_LEVEL = "batterylevel";
public static final String CHANNEL_HVAC_STATUS = "hvacstatus";
public static final String CHANNEL_IMAGE = "image";
public static final String CHANNEL_LOCATION = "location";
public static final String CHANNEL_ODOMETER = "odometer";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Copyright (c) 2010-2021 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.renault.internal;

/**
* The {@link RenaultConfiguration} class contains fields mapping thing configuration parameters.
*
* @author Doug Culnane - Initial contribution
*/
public class RenaultConfiguration {
lolodomo marked this conversation as resolved.
Show resolved Hide resolved

public String myRenaultUsername;
public String myRenaultPassword;
public String locale;
public String vin;
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
public int refreshInterval;
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/**
* Copyright (c) 2010-2021 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.renault.internal;
lolodomo marked this conversation as resolved.
Show resolved Hide resolved

import static org.openhab.binding.renault.internal.RenaultBindingConstants.*;

import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.renault.internal.renault.api.Car;
import org.openhab.binding.renault.internal.renault.api.MyRenaultHttpSession;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.PointType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingStatusDetail;
import org.openhab.core.thing.binding.BaseThingHandler;
import org.openhab.core.types.Command;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* The {@link RenaultHandler} is responsible for handling commands, which are
* sent to one of the channels.
*
* @author Doug Culnane - Initial contribution
*/
@NonNullByDefault
public class RenaultHandler extends BaseThingHandler {

private final Logger logger = LoggerFactory.getLogger(RenaultHandler.class);

private @Nullable RenaultConfiguration config;

private @Nullable ScheduledFuture<?> pollingJob;

public RenaultHandler(Thing thing) {
super(thing);
}

@Override
public void handleCommand(ChannelUID channelUID, Command command) {
// This binding only polls status data automatically.
}

@Override
public void initialize() {
updateStatus(ThingStatus.UNKNOWN);
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
this.config = getConfigAs(RenaultConfiguration.class);

lolodomo marked this conversation as resolved.
Show resolved Hide resolved
// Background initialization:
if (pollingJob == null || pollingJob.isCancelled()) {
pollingJob = scheduler.scheduleWithFixedDelay(this::getStatus, 0, config.refreshInterval, TimeUnit.MINUTES);
}
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
}

@Override
public void dispose() {
if (pollingJob != null) {
pollingJob.cancel(true);
pollingJob = null;
}
super.dispose();
}
lolodomo marked this conversation as resolved.
Show resolved Hide resolved

private void getStatus() {
MyRenaultHttpSession httpSession;
try {
httpSession = new MyRenaultHttpSession(this.config);
updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE);
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
httpSession.updateCarData(this.config);
updateState(httpSession.getCar());
} catch (Exception e) {
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
httpSession = null;
logger.error("Error My Renault Http Session.", e);
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
}
}

private void updateState(Car car) {
if (car.batteryLevel != null) {
updateState(CHANNEL_BATTERY_LEVEL, new DecimalType(car.batteryLevel));
}
if (car.hvacstatus != null) {
updateState(CHANNEL_HVAC_STATUS, (car.hvacstatus ? OnOffType.ON : OnOffType.OFF));
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
}
if (car.imageURL != null) {
updateState(CHANNEL_IMAGE, new StringType(car.imageURL));
}
if (car.gpsLatitude != null && car.gpsLongitude != null) {
updateState(CHANNEL_LOCATION,
new PointType(new DecimalType(car.gpsLatitude), new DecimalType(car.gpsLongitude)));
}
if (car.odometer != null) {
updateState(CHANNEL_ODOMETER, new DecimalType(car.odometer));
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* Copyright (c) 2010-2021 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.renault.internal;

import static org.openhab.binding.renault.internal.RenaultBindingConstants.*;

import java.util.Set;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.thing.binding.ThingHandlerFactory;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;

/**
* The {@link RenaultHandlerFactory} is responsible for creating things and thing
* handlers.
*
* @author Doug Culnane - Initial contribution
*/
@NonNullByDefault
@Component(configurationPid = "binding.renault", service = ThingHandlerFactory.class)
public class RenaultHandlerFactory extends BaseThingHandlerFactory {

private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_CAR);

@Activate
public RenaultHandlerFactory() {
}

@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
}

@Override
protected @Nullable ThingHandler createHandler(Thing thing) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();

if (THING_TYPE_CAR.equals(thingTypeUID)) {
return new RenaultHandler(thing);
}

return null;
}
}
Loading