[meteofrance] New binding (#15462)
* Adapting binding to new data feed Signed-off-by: clinique <gael@lhopital.org>
@ -211,8 +211,8 @@
|
||||
/bundles/org.openhab.binding.mecmeter/ @kaikreuzer
|
||||
/bundles/org.openhab.binding.melcloud/ @lucacalcaterra @paulianttila @thewiep
|
||||
/bundles/org.openhab.binding.mercedesme/ @weymann
|
||||
/bundles/org.openhab.binding.meteoalerte/ @clinique
|
||||
/bundles/org.openhab.binding.meteoblue/ @9037568
|
||||
/bundles/org.openhab.binding.meteofrance/ @clinique
|
||||
/bundles/org.openhab.binding.meteostick/ @cdjackson
|
||||
/bundles/org.openhab.binding.mffan/ @mark-brooks-180
|
||||
/bundles/org.openhab.binding.miele/ @kgoderis @jlaur
|
||||
|
@ -1053,12 +1053,12 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.binding.meteoalerte</artifactId>
|
||||
<artifactId>org.openhab.binding.meteoblue</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.binding.meteoblue</artifactId>
|
||||
<artifactId>org.openhab.binding.meteofrance</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -1,113 +0,0 @@
|
||||
# Meteo Alerte Binding
|
||||
|
||||
The Meteo Alerte binding gives alert level regarding major weather related risk factors.
|
||||
This binding provides its own icon set and provides appropriate static and dynamic SVG icons (see items examples below).
|
||||
|
||||
## Supported Things
|
||||
|
||||
There is exactly one supported thing type, which represents the weather alerts for a given department.
|
||||
It has the `department` id.
|
||||
Of course, you can add multiple things, e.g. for getting alerts for different locations.
|
||||
|
||||
## Binding Configuration
|
||||
|
||||
The binding has no configuration options, all configuration is done at Thing level.
|
||||
|
||||
## Thing Configuration
|
||||
|
||||
The thing has a few configuration parameters:
|
||||
|
||||
| Parameter | Description |
|
||||
|---------------|----------------------------------------------------------------------------------------|
|
||||
| `department` | Name of the department. |
|
||||
| refresh | Refresh interval in minutes. Optional, the default value is 1440 minutes (once a day). |
|
||||
|
||||
## Channels
|
||||
|
||||
The Météo Alerte information that are retrieved is available as these channels:
|
||||
|
||||
| Channel ID | Item Type | Description |
|
||||
|-----------------------|-----------|-----------------------------------------------|
|
||||
| observation-time | DateTime | Date and time of report validity start |
|
||||
| end-time | DateTime | Date and time of report validity end |
|
||||
| comment | String | General comments on alerts for the department |
|
||||
| vent | Number | Wind alert level (*) |
|
||||
| pluie-inondation | Number | Rain alert level (*) |
|
||||
| orage | Number | Storm alert level (*) |
|
||||
| inondation | Number | Flood alert level (*) |
|
||||
| neige | Number | Snow alert level (*) |
|
||||
| canicule | Number | Heat alert level (*) |
|
||||
| grand-froid | Number | Cold alert level (*) |
|
||||
| avalanches | Number | Avalanche alert level (*) |
|
||||
| vague-submersion | Number | Wave submersion alert level (*) |
|
||||
| pluie-inondation-icon | Image | Pictogram of the Rain alert level |
|
||||
| vent-icon | Image | Pictogram of the Wind alert level |
|
||||
| orage-icon | Image | Pictogram of Storm alert level |
|
||||
| inondation-icon | Image | Pictogram of Flood alert level |
|
||||
| neige-icon | Image | Pictogram of Snow alert level |
|
||||
| canicule-icon | Image | Pictogram of Heat alert level |
|
||||
| grand-froid-icon | Image | Pictogram of Cold alert level |
|
||||
| avalanches-icon | Image | Pictogram of Avalanche alert level |
|
||||
| vague-submersion-icon | Image | Pictogram of Wave Submersion alert level |
|
||||
|
||||
(*) Each alert level is described by a color :
|
||||
|
||||
| Code | Color | Description |
|
||||
|------|--------|-------------------------------------------|
|
||||
| 0 | Green | No particular vigilance |
|
||||
| 1 | Yellow | Be attentive to the weather situation |
|
||||
| 2 | Orange | Be "very vigilant" in the concerned areas |
|
||||
| 3 | Red | Absolute vigilance required |
|
||||
|
||||
## Provided icon set
|
||||
|
||||
This binding has its own IconProvider and makes available the following list of icons
|
||||
|
||||
| Icon Name | Dynamic | Illustration |
|
||||
|---------------------------------|---------|--------------|
|
||||
| oh:meteoalerte:vent | Yes | ![](src/main/resources/icon/vent.svg) |
|
||||
| oh:meteoalerte:pluie-inondation | Yes | ![](src/main/resources/icon/pluie-inondation.svg) |
|
||||
| oh:meteoalerte:orage | Yes | ![](src/main/resources/icon/orage.svg) |
|
||||
| oh:meteoalerte:inondation | Yes | ![](src/main/resources/icon/inondation.svg) |
|
||||
| oh:meteoalerte:neige | Yes | ![](src/main/resources/icon/neige.svg) |
|
||||
| oh:meteoalerte:canicule | Yes | ![](src/main/resources/icon/canicule.svg) |
|
||||
| oh:meteoalerte:grand-froid | Yes | ![](src/main/resources/icon/grand-froid.svg) |
|
||||
| oh:meteoalerte:avalanches | Yes | ![](src/main/resources/icon/avalanches.svg) |
|
||||
| oh:meteoalerte:vague-submersion | Yes | ![](src/main/resources/icon/vague-submersion.svg) |
|
||||
| oh:meteoalerte:meteo_france | No | ![](src/main/resources/icon/meteo_france.svg) |
|
||||
|
||||
|
||||
## Full Example
|
||||
|
||||
meteoalert.things:
|
||||
|
||||
```java
|
||||
Thing meteoalerte:department:yvelines @ "MyCity" [department="YVELINES", refresh=12]
|
||||
```
|
||||
|
||||
meteoalert.items:
|
||||
|
||||
```java
|
||||
Group gMeteoAlert "Alertes Météo" <oh:meteoalerte:meteo_france>
|
||||
String MA_Dept78 "Département 78 [%s]" <text> (gMeteoAlert) {channel="meteoalerte:department:yvelines:comment"}
|
||||
Number MA_etat_canicule "Canicule [%s]" <oh:meteoalerte:canicule> (gMeteoAlert) {channel="meteoalerte:department:yvelines:canicule"}
|
||||
Number MA_etat_grand_froid "Grand Froid [%s]" <oh:meteoalerte:grand-froid> (gMeteoAlert) {channel="meteoalerte:department:yvelines:grand-froid"}
|
||||
Number MA_etat_pluie_inondation "Pluie-Inondation [%s]" <oh:meteoalerte:pluie-inondation> (gMeteoAlert) {channel="meteoalerte:department:yvelines:pluie-inondation"}
|
||||
Number MA_etat_neige "Neige [%s]" <oh:meteoalerte:neige> (gMeteoAlert) {channel="meteoalerte:department:yvelines:neige"}
|
||||
Number MA_etat_vent "Vent [%s]" <oh:meteoalerte:vent> (gMeteoAlert) {channel="meteoalerte:department:yvelines:vent"}
|
||||
Number MA_etat_inondation "Inondation [%s]" <oh:meteoalerte:inondation> (gMeteoAlert) {channel="meteoalerte:department:yvelines:inondation"}
|
||||
Number MA_etat_orage "Orage [%s]" <oh:meteoalerte:orage> (gMeteoAlert) {channel="meteoalerte:department:yvelines:orage"}
|
||||
Number MA_etat_avalanche "Avalanches [%s]" <oh:meteoalerte:avalanches> (gMeteoAlert) {channel="meteoalerte:department:yvelines:avalanches"}
|
||||
|
||||
Image MA_icon_canicule "Canicule" <oh:meteoalerte:canicule> (gMeteoAlert) {channel="meteoalerte:department:yvelines:canicule-icon"}
|
||||
Image MA_icon_grand_froid "Grand Froid" <oh:meteoalerte:grand-froid> (gMeteoAlert) {channel="meteoalerte:department:yvelines:grand-froid-icon"}
|
||||
Image MA_icon_pluie_inondation "Pluie-Inondation" <oh:meteoalerte:pluie-inondation> (gMeteoAlert) {channel="meteoalerte:department:yvelines:pluie-inondation-icon"}
|
||||
Image MA_icon_neige "Neige" <oh:meteoalerte:neige> (gMeteoAlert) {channel="meteoalerte:department:yvelines:neige-icon"}
|
||||
Image MA_icon_vent "Vent" <oh:meteoalerte:vent> (gMeteoAlert) {channel="meteoalerte:department:yvelines:vent-icon"}
|
||||
Image MA_icon_inondation "Inondation" <oh:meteoalerte:inondation> (gMeteoAlert) {channel="meteoalerte:department:yvelines:inondation-icon"}
|
||||
Image MA_icon_orage "Orage" <oh:meteoalerte:orage> (gMeteoAlert) {channel="meteoalerte:department:yvelines:orage-icon"}
|
||||
Image MA_icon_avalanche "Avalanche" <oh:meteoalerte:avalanches> (gMeteoAlert) {channel="meteoalerte:department:yvelines:avalanches-icon"}
|
||||
|
||||
DateTime MA_ObservationTS "Timestamp [%1$tH:%1$tM]" <time> (gMeteoAlert) {channel="meteoalerte:department:yvelines:observation-time"}
|
||||
|
||||
```
|
@ -1,44 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteoalerte.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link MeteoAlerteBindingConstants} class defines common constants, which are
|
||||
* used across the whole binding.
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class MeteoAlerteBindingConstants {
|
||||
public static final String BINDING_ID = "meteoalerte";
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
public static final ThingTypeUID THING_TYPE_METEO_ALERT = new ThingTypeUID(BINDING_ID, "department");
|
||||
|
||||
// List of all Channel IDs
|
||||
public static final String WAVE = "vague-submersion";
|
||||
public static final String AVALANCHE = "avalanches";
|
||||
public static final String HEAT = "canicule";
|
||||
public static final String FREEZE = "grand-froid";
|
||||
public static final String FLOOD = "inondation";
|
||||
public static final String SNOW = "neige";
|
||||
public static final String STORM = "orage";
|
||||
public static final String RAIN = "pluie-inondation";
|
||||
public static final String WIND = "vent";
|
||||
public static final String OBSERVATION_TIME = "observation-time";
|
||||
public static final String END_TIME = "end-time";
|
||||
public static final String COMMENT = "comment";
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteoalerte.internal;
|
||||
|
||||
import static org.openhab.binding.meteoalerte.internal.MeteoAlerteBindingConstants.THING_TYPE_METEO_ALERT;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.meteoalerte.internal.handler.MeteoAlerteHandler;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
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;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
|
||||
/**
|
||||
* The {@link MeteoAlerteHandlerFactory} is responsible for creating things and thing handlers.
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@Component(service = ThingHandlerFactory.class)
|
||||
@NonNullByDefault
|
||||
public class MeteoAlerteHandlerFactory extends BaseThingHandlerFactory {
|
||||
private final Gson gson;
|
||||
private final MeteoAlertIconProvider iconProvider;
|
||||
|
||||
@Activate
|
||||
public MeteoAlerteHandlerFactory(@Reference TimeZoneProvider timeZoneProvider,
|
||||
@Reference MeteoAlertIconProvider iconProvider) {
|
||||
this.iconProvider = iconProvider;
|
||||
this.gson = new GsonBuilder().registerTypeAdapter(ZonedDateTime.class,
|
||||
(JsonDeserializer<ZonedDateTime>) (json, type, jsonDeserializationContext) -> ZonedDateTime
|
||||
.parse(json.getAsJsonPrimitive().getAsString())
|
||||
.withZoneSameInstant(timeZoneProvider.getTimeZone()))
|
||||
.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return THING_TYPE_METEO_ALERT.equals(thingTypeUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
return supportsThingType(thingTypeUID) ? new MeteoAlerteHandler(thing, gson, iconProvider) : null;
|
||||
}
|
||||
}
|
@ -1,176 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteoalerte.internal.handler;
|
||||
|
||||
import static org.openhab.binding.meteoalerte.internal.MeteoAlerteBindingConstants.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.meteoalerte.internal.MeteoAlertIconProvider;
|
||||
import org.openhab.binding.meteoalerte.internal.MeteoAlerteConfiguration;
|
||||
import org.openhab.binding.meteoalerte.internal.json.ApiResponse;
|
||||
import org.openhab.binding.meteoalerte.internal.json.ResponseFieldDTO.AlertLevel;
|
||||
import org.openhab.core.io.net.http.HttpUtil;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.RawType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
/**
|
||||
* The {@link MeteoAlerteHandler} is responsible for updating channels
|
||||
* and querying the API
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class MeteoAlerteHandler extends BaseThingHandler {
|
||||
private static final int TIMEOUT_MS = 30000;
|
||||
private static final String URL = """
|
||||
https://public.opendatasoft.com/api/records/1.0/search/?dataset=risques-meteorologiques-copy&\
|
||||
facet=etat_vent&facet=etat_pluie_inondation&facet=etat_orage&facet=etat_inondation&facet=etat_neige&facet=etat_canicule&\
|
||||
facet=etat_grand_froid&facet=etat_avalanches&refine.nom_dept=%s\
|
||||
""";
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(MeteoAlerteHandler.class);
|
||||
private final MeteoAlertIconProvider iconProvider;
|
||||
private final Gson gson;
|
||||
|
||||
private Optional<ScheduledFuture<?>> refreshJob = Optional.empty();
|
||||
private String queryUrl = "";
|
||||
|
||||
public MeteoAlerteHandler(Thing thing, Gson gson, MeteoAlertIconProvider iconProvider) {
|
||||
super(thing);
|
||||
this.gson = gson;
|
||||
this.iconProvider = iconProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
logger.debug("Initializing Météo Alerte handler.");
|
||||
|
||||
MeteoAlerteConfiguration config = getConfigAs(MeteoAlerteConfiguration.class);
|
||||
logger.debug("config department = {}", config.department);
|
||||
logger.debug("config refresh = {}", config.refresh);
|
||||
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
queryUrl = URL.formatted(config.department);
|
||||
refreshJob = Optional
|
||||
.of(scheduler.scheduleWithFixedDelay(this::updateAndPublish, 0, config.refresh, TimeUnit.MINUTES));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
logger.debug("Disposing the Météo Alerte handler.");
|
||||
|
||||
refreshJob.ifPresent(job -> job.cancel(true));
|
||||
refreshJob = Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (command instanceof RefreshType) {
|
||||
updateAndPublish();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAndPublish() {
|
||||
try {
|
||||
if (queryUrl.isEmpty()) {
|
||||
throw new MalformedURLException("queryUrl not initialized");
|
||||
}
|
||||
String response = HttpUtil.executeUrl("GET", queryUrl, TIMEOUT_MS);
|
||||
if (response == null) {
|
||||
throw new IOException("Empty response");
|
||||
}
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
updateChannels(Objects.requireNonNull(gson.fromJson(response, ApiResponse.class)));
|
||||
} catch (MalformedURLException e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||
"Querying '%s' error : %s".formatted(queryUrl, e.getMessage()));
|
||||
} catch (IOException e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the channel from the last Meteo Alerte data retrieved
|
||||
*
|
||||
* @param channelId the id identifying the channel to be updated
|
||||
*/
|
||||
private void updateChannels(ApiResponse apiResponse) {
|
||||
apiResponse.getRecords().findFirst().ifPresent(record -> record.getResponseFieldDTO().ifPresent(fields -> {
|
||||
updateAlert(WIND, fields.getVent());
|
||||
updateAlert(RAIN, fields.getPluieInondation());
|
||||
updateAlert(STORM, fields.getOrage());
|
||||
updateAlert(FLOOD, fields.getInondation());
|
||||
updateAlert(SNOW, fields.getNeige());
|
||||
updateAlert(HEAT, fields.getCanicule());
|
||||
updateAlert(FREEZE, fields.getGrandFroid());
|
||||
updateAlert(AVALANCHE, fields.getAvalanches());
|
||||
updateAlert(WAVE, fields.getVagueSubmersion());
|
||||
updateState(COMMENT, StringType.valueOf(fields.getVigilanceComment()));
|
||||
fields.getDateInsert().ifPresent(date -> updateDate(OBSERVATION_TIME, date));
|
||||
fields.getDatePrevue().ifPresent(date -> updateDate(END_TIME, date));
|
||||
}));
|
||||
}
|
||||
|
||||
private void updateAlert(String channelId, AlertLevel value) {
|
||||
State state = value != AlertLevel.UNKNOWN ? new DecimalType(value.ordinal()) : UnDefType.NULL;
|
||||
if (isLinked(channelId)) {
|
||||
updateState(channelId, state);
|
||||
}
|
||||
|
||||
String channelIcon = channelId + "-icon";
|
||||
if (isLinked(channelIcon)) {
|
||||
InputStream icon = iconProvider.getIcon(channelId, state.toString());
|
||||
if (icon != null) {
|
||||
try {
|
||||
State result = new RawType(icon.readAllBytes(), "image/svg+xml");
|
||||
updateState(channelIcon, result);
|
||||
} catch (IOException e) {
|
||||
logger.warn("Error getting icon for channel {} and value {} : {}", channelId, value,
|
||||
e.getMessage());
|
||||
}
|
||||
} else {
|
||||
logger.warn("Null icon returned for channel {} and state {}", channelIcon, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDate(String channelId, ZonedDateTime zonedDateTime) {
|
||||
if (isLinked(channelId)) {
|
||||
updateState(channelId, new DateTimeType(zonedDateTime));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteoalerte.internal.json;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* The {@link ApiResponse} is the Java class used to map the JSON
|
||||
* response to the webservice request.
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ApiResponse {
|
||||
@SerializedName("nhits")
|
||||
private int nHits;
|
||||
private @Nullable Parameters parameters;
|
||||
private List<Record> records = new ArrayList<>();
|
||||
|
||||
public int getNHits() {
|
||||
return nHits;
|
||||
}
|
||||
|
||||
public Optional<Parameters> getParameters() {
|
||||
return Optional.ofNullable(parameters);
|
||||
}
|
||||
|
||||
public Stream<Record> getRecords() {
|
||||
return records.stream();
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteoalerte.internal.json;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* The {@link Parameters} is the Java class used to map the JSON
|
||||
* response to the webservice request.
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class Parameters {
|
||||
private String dataset = "";
|
||||
@SerializedName("timezone")
|
||||
private String timeZone = "";
|
||||
private int rows;
|
||||
private String format = "";
|
||||
private @Nullable Refine refine;
|
||||
|
||||
public String getDataset() {
|
||||
return dataset;
|
||||
}
|
||||
|
||||
public String getTimezone() {
|
||||
return timeZone;
|
||||
}
|
||||
|
||||
public int getRows() {
|
||||
return rows;
|
||||
}
|
||||
|
||||
public String getFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
public Optional<Refine> getRefine() {
|
||||
return Optional.ofNullable(refine);
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteoalerte.internal.json;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* The {@link Record} is the Java class used to map the JSON
|
||||
* response to the webservice request.
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class Record {
|
||||
@SerializedName("datasetid")
|
||||
private String datasetId = "";
|
||||
@SerializedName("recordid")
|
||||
private String recordId = "";
|
||||
@SerializedName("record_timestamp")
|
||||
private String recordTimestamp = "";
|
||||
@SerializedName("fields")
|
||||
private @Nullable ResponseFieldDTO responseFieldDTO;
|
||||
|
||||
public String getDatasetId() {
|
||||
return datasetId;
|
||||
}
|
||||
|
||||
public String getRecordId() {
|
||||
return recordId;
|
||||
}
|
||||
|
||||
public String getRecordTimestamp() {
|
||||
return recordTimestamp;
|
||||
}
|
||||
|
||||
public Optional<ResponseFieldDTO> getResponseFieldDTO() {
|
||||
return Optional.ofNullable(responseFieldDTO);
|
||||
}
|
||||
}
|
@ -1,161 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteoalerte.internal.json;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* The {@link ResponseFieldDTO} is the Java class used to map the JSON
|
||||
* response to the webservice request.
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ResponseFieldDTO {
|
||||
public enum AlertLevel {
|
||||
@SerializedName("Vert")
|
||||
GREEN("00ff00"),
|
||||
@SerializedName("Jaune")
|
||||
YELLOW("ffff00"),
|
||||
@SerializedName("Orange")
|
||||
ORANGE("ef6c00"),
|
||||
@SerializedName("Rouge")
|
||||
RED("ff0000"),
|
||||
UNKNOWN("3d3c3c");
|
||||
|
||||
public final String color;
|
||||
|
||||
AlertLevel(String color) {
|
||||
this.color = color;
|
||||
}
|
||||
}
|
||||
|
||||
@SerializedName("nom_reg")
|
||||
private String nomReg = "";
|
||||
@SerializedName("typeprev")
|
||||
private String typePrev = "";
|
||||
@SerializedName("etat_canicule")
|
||||
private AlertLevel canicule = AlertLevel.UNKNOWN;
|
||||
@SerializedName("nom_dept")
|
||||
private String nomDept = "";
|
||||
@SerializedName("etat_grand_froid")
|
||||
private AlertLevel grandFroid = AlertLevel.UNKNOWN;
|
||||
@SerializedName("noversion")
|
||||
private String noVersion = "";
|
||||
@SerializedName("etat_pluie_inondation")
|
||||
private AlertLevel pluieInondation = AlertLevel.UNKNOWN;
|
||||
@SerializedName("etat_neige")
|
||||
private AlertLevel neige = AlertLevel.UNKNOWN;
|
||||
@SerializedName("etat_vent")
|
||||
private AlertLevel vent = AlertLevel.UNKNOWN;
|
||||
@SerializedName("etat_inondation")
|
||||
private AlertLevel inondation = AlertLevel.UNKNOWN;
|
||||
@SerializedName("etat_avalanches")
|
||||
private AlertLevel avalanches = AlertLevel.UNKNOWN;
|
||||
@SerializedName("etat_orage")
|
||||
private AlertLevel orage = AlertLevel.UNKNOWN;
|
||||
private int echeance;
|
||||
@SerializedName("etat_vague_submersion")
|
||||
private AlertLevel vagueSubmersion = AlertLevel.UNKNOWN;
|
||||
private String dep = "";
|
||||
@SerializedName("vigilancecommentaire_texte")
|
||||
private String vigilanceComment = "";
|
||||
@SerializedName("dateprevue")
|
||||
private @Nullable ZonedDateTime datePrevue;
|
||||
@SerializedName("dateinsert")
|
||||
private @Nullable ZonedDateTime dateInsert;
|
||||
@SerializedName("daterun")
|
||||
private @Nullable ZonedDateTime dateRun;
|
||||
|
||||
public String getVigilanceComment() {
|
||||
return vigilanceComment;
|
||||
}
|
||||
|
||||
public String getNomReg() {
|
||||
return nomReg;
|
||||
}
|
||||
|
||||
public Optional<ZonedDateTime> getDatePrevue() {
|
||||
return Optional.ofNullable(datePrevue);
|
||||
}
|
||||
|
||||
public String getTypePrev() {
|
||||
return typePrev;
|
||||
}
|
||||
|
||||
public AlertLevel getCanicule() {
|
||||
return canicule;
|
||||
}
|
||||
|
||||
public String getNomDept() {
|
||||
return nomDept;
|
||||
}
|
||||
|
||||
public AlertLevel getGrandFroid() {
|
||||
return grandFroid;
|
||||
}
|
||||
|
||||
public String getNoVersion() {
|
||||
return noVersion;
|
||||
}
|
||||
|
||||
public AlertLevel getPluieInondation() {
|
||||
return pluieInondation;
|
||||
}
|
||||
|
||||
public AlertLevel getNeige() {
|
||||
return neige;
|
||||
}
|
||||
|
||||
public AlertLevel getVent() {
|
||||
return vent;
|
||||
}
|
||||
|
||||
public Optional<ZonedDateTime> getDateInsert() {
|
||||
return Optional.ofNullable(dateInsert);
|
||||
}
|
||||
|
||||
public AlertLevel getInondation() {
|
||||
return inondation;
|
||||
}
|
||||
|
||||
public AlertLevel getAvalanches() {
|
||||
return avalanches;
|
||||
}
|
||||
|
||||
public AlertLevel getOrage() {
|
||||
return orage;
|
||||
}
|
||||
|
||||
public int getEcheance() {
|
||||
return echeance;
|
||||
}
|
||||
|
||||
public AlertLevel getVagueSubmersion() {
|
||||
return vagueSubmersion;
|
||||
}
|
||||
|
||||
public String getDep() {
|
||||
return dep;
|
||||
}
|
||||
|
||||
public Optional<ZonedDateTime> getDateRun() {
|
||||
return Optional.ofNullable(dateRun);
|
||||
}
|
||||
}
|
@ -1,189 +0,0 @@
|
||||
# add-on
|
||||
|
||||
addon.meteoalerte.name = Meteo Alerte Binding
|
||||
addon.meteoalerte.description = Retrieves Meteo Alert levels in France
|
||||
|
||||
# thing types
|
||||
|
||||
thing-type.meteoalerte.department.label = Alertes Département
|
||||
thing-type.meteoalerte.department.description = Fournit les niveaux d'alerte météo pour un département.
|
||||
thing-type.meteoalerte.department.channel.avalanches-icon.label = Icône Avalanches
|
||||
thing-type.meteoalerte.department.channel.canicule-icon.label = Icône Canicule
|
||||
thing-type.meteoalerte.department.channel.end-time.label = Fin de validité
|
||||
thing-type.meteoalerte.department.channel.grand-froid-icon.label = Icône Grand Froid
|
||||
thing-type.meteoalerte.department.channel.inondation-icon.label = Icône Inondation
|
||||
thing-type.meteoalerte.department.channel.neige-icon.label = Icône Neige
|
||||
thing-type.meteoalerte.department.channel.observation-time.label = Début de validité
|
||||
thing-type.meteoalerte.department.channel.orage-icon.label = Icône Orage
|
||||
thing-type.meteoalerte.department.channel.pluie-inondation-icon.label = Icône Pluie Inondation
|
||||
thing-type.meteoalerte.department.channel.vague-submersion-icon.label = Icône Vague Submersion
|
||||
thing-type.meteoalerte.department.channel.vent-icon.label = Icône Vent
|
||||
|
||||
# thing types config
|
||||
|
||||
thing-type.config.meteoalerte.department.department.label = Département
|
||||
thing-type.config.meteoalerte.department.department.description = Nom du département
|
||||
thing-type.config.meteoalerte.department.department.option.AIN = Ain
|
||||
thing-type.config.meteoalerte.department.department.option.AISNE = Aisne
|
||||
thing-type.config.meteoalerte.department.department.option.ALLIER = Allier
|
||||
thing-type.config.meteoalerte.department.department.option.ALPES-DE-HAUTE-PROVENCE = Alpes de Haute Provence
|
||||
thing-type.config.meteoalerte.department.department.option.ALPES-MARITIMES = Alpes Maritimes
|
||||
thing-type.config.meteoalerte.department.department.option.ARDECHE = Ardèche
|
||||
thing-type.config.meteoalerte.department.department.option.ARDENNES = Ardennes
|
||||
thing-type.config.meteoalerte.department.department.option.ARIEGE = Ariège
|
||||
thing-type.config.meteoalerte.department.department.option.AUBE = Aube
|
||||
thing-type.config.meteoalerte.department.department.option.AUDE = Aude
|
||||
thing-type.config.meteoalerte.department.department.option.AVEYRON = Aveyron
|
||||
thing-type.config.meteoalerte.department.department.option.BAS-RHIN = Bas-Rhin
|
||||
thing-type.config.meteoalerte.department.department.option.BOUCHES-DU-RHONE = Bouches du Rhône
|
||||
thing-type.config.meteoalerte.department.department.option.CALVADOS = Calvados
|
||||
thing-type.config.meteoalerte.department.department.option.CANTAL = Cantal
|
||||
thing-type.config.meteoalerte.department.department.option.CHARENTE = Charente
|
||||
thing-type.config.meteoalerte.department.department.option.CHARENTE-MARITIME = Charente Maritime
|
||||
thing-type.config.meteoalerte.department.department.option.CHER = Cher
|
||||
thing-type.config.meteoalerte.department.department.option.CORREZE = Corrèze
|
||||
thing-type.config.meteoalerte.department.department.option.CORSE-DU-SUD = Corse du Sud
|
||||
thing-type.config.meteoalerte.department.department.option.COTE-D'OR = Côte D'Or
|
||||
thing-type.config.meteoalerte.department.department.option.COTES-D'ARMOR = Côtes D'Armor
|
||||
thing-type.config.meteoalerte.department.department.option.CREUSE = Creuse
|
||||
thing-type.config.meteoalerte.department.department.option.DEUX-SEVRES = Deux Sèvres
|
||||
thing-type.config.meteoalerte.department.department.option.DORDOGNE = Dordogne
|
||||
thing-type.config.meteoalerte.department.department.option.DOUBS = Doubs
|
||||
thing-type.config.meteoalerte.department.department.option.DROME = Drôme
|
||||
thing-type.config.meteoalerte.department.department.option.ESSONNE = Essonne
|
||||
thing-type.config.meteoalerte.department.department.option.EURE = Eure
|
||||
thing-type.config.meteoalerte.department.department.option.EURE-ET-LOIR = Eure et Loir
|
||||
thing-type.config.meteoalerte.department.department.option.FINISTERE = Finistère
|
||||
thing-type.config.meteoalerte.department.department.option.GARD = Gard
|
||||
thing-type.config.meteoalerte.department.department.option.GERS = Gers
|
||||
thing-type.config.meteoalerte.department.department.option.GIRONDE = Gironde
|
||||
thing-type.config.meteoalerte.department.department.option.HAUT-RHIN = Haut-Rhin
|
||||
thing-type.config.meteoalerte.department.department.option.HAUTE-CORSE = Haute Corse
|
||||
thing-type.config.meteoalerte.department.department.option.HAUTE-GARONNE = Haute Garonne
|
||||
thing-type.config.meteoalerte.department.department.option.HAUTE-LOIRE = Haute Loire
|
||||
thing-type.config.meteoalerte.department.department.option.HAUTE-MARNE = Haute Marne
|
||||
thing-type.config.meteoalerte.department.department.option.HAUTE-SAONE = Haute Saône
|
||||
thing-type.config.meteoalerte.department.department.option.HAUTE-SAVOIE = Haute Savoie
|
||||
thing-type.config.meteoalerte.department.department.option.HAUTE-VIENNE = Haute Vienne
|
||||
thing-type.config.meteoalerte.department.department.option.HAUTES-ALPES = Hautes Alpes
|
||||
thing-type.config.meteoalerte.department.department.option.HAUTES-PYRENEES = Hautes Pyrénées
|
||||
thing-type.config.meteoalerte.department.department.option.HAUTS-DE-SEINE = Hauts de Seine
|
||||
thing-type.config.meteoalerte.department.department.option.HERAULT = Hérault
|
||||
thing-type.config.meteoalerte.department.department.option.ILLE-ET-VILAINE = Ille et Vilaine
|
||||
thing-type.config.meteoalerte.department.department.option.INDRE = Indre
|
||||
thing-type.config.meteoalerte.department.department.option.INDRE-ET-LOIRE = Indre et Loire
|
||||
thing-type.config.meteoalerte.department.department.option.ISERE = Isère
|
||||
thing-type.config.meteoalerte.department.department.option.JURA = Jura
|
||||
thing-type.config.meteoalerte.department.department.option.LANDES = Landes
|
||||
thing-type.config.meteoalerte.department.department.option.LOIR-ET-CHER = Loir et Cher
|
||||
thing-type.config.meteoalerte.department.department.option.LOIRE = Loire
|
||||
thing-type.config.meteoalerte.department.department.option.LOIRE-ATLANTIQUE = Loire Atlantique
|
||||
thing-type.config.meteoalerte.department.department.option.LOIRET = Loiret
|
||||
thing-type.config.meteoalerte.department.department.option.LOT = Lot
|
||||
thing-type.config.meteoalerte.department.department.option.LOT-ET-GARONNE = Lot et Garonne
|
||||
thing-type.config.meteoalerte.department.department.option.LOZERE = Lozère
|
||||
thing-type.config.meteoalerte.department.department.option.MAINE-ET-LOIRE = Maine et Loire
|
||||
thing-type.config.meteoalerte.department.department.option.MANCHE = Manche
|
||||
thing-type.config.meteoalerte.department.department.option.MARNE = Marne
|
||||
thing-type.config.meteoalerte.department.department.option.MAYENNE = Mayenne
|
||||
thing-type.config.meteoalerte.department.department.option.MEURTHE-ET-MOSELLE = Meurthe et Moselle
|
||||
thing-type.config.meteoalerte.department.department.option.MEUSE = Meuse
|
||||
thing-type.config.meteoalerte.department.department.option.MORBIHAN = Morbihan
|
||||
thing-type.config.meteoalerte.department.department.option.MOSELLE = Moselle
|
||||
thing-type.config.meteoalerte.department.department.option.NIEVRE = Nièvre
|
||||
thing-type.config.meteoalerte.department.department.option.NORD = Nord
|
||||
thing-type.config.meteoalerte.department.department.option.OISE = Oise
|
||||
thing-type.config.meteoalerte.department.department.option.ORNE = Orne
|
||||
thing-type.config.meteoalerte.department.department.option.PARIS = Paris
|
||||
thing-type.config.meteoalerte.department.department.option.PAS-DE-CALAIS = Pas de Calais
|
||||
thing-type.config.meteoalerte.department.department.option.PUY-DE-DOME = Puy de Dôme
|
||||
thing-type.config.meteoalerte.department.department.option.PYRENEES-ATLANTIQUES = Pyrénées Atlantiques
|
||||
thing-type.config.meteoalerte.department.department.option.PYRENEES-ORIENTALES = Pyrénées Orientales
|
||||
thing-type.config.meteoalerte.department.department.option.RHONE = Rhône
|
||||
thing-type.config.meteoalerte.department.department.option.SAONE-ET-LOIRE = Saône et Loire
|
||||
thing-type.config.meteoalerte.department.department.option.SARTHE = Sarthe
|
||||
thing-type.config.meteoalerte.department.department.option.SAVOIE = Savoie
|
||||
thing-type.config.meteoalerte.department.department.option.SEINE-ET-MARNE = Seine et Marne
|
||||
thing-type.config.meteoalerte.department.department.option.SEINE-MARITIME = Seine Maritime
|
||||
thing-type.config.meteoalerte.department.department.option.SEINE-SAINT-DENIS = Seine Saint Denis
|
||||
thing-type.config.meteoalerte.department.department.option.SOMME = Somme
|
||||
thing-type.config.meteoalerte.department.department.option.TARN = Tarn
|
||||
thing-type.config.meteoalerte.department.department.option.TARN-ET-GARONNE = Tarn et Garonne
|
||||
thing-type.config.meteoalerte.department.department.option.TERRITOIRE\ DE\ BELFORT = Territoire de Belfort
|
||||
thing-type.config.meteoalerte.department.department.option.VAL-D'OISE = Val D'Oise
|
||||
thing-type.config.meteoalerte.department.department.option.VAL-DE-MARNE = Val de Marne
|
||||
thing-type.config.meteoalerte.department.department.option.VAR = Var
|
||||
thing-type.config.meteoalerte.department.department.option.VAUCLUSE = Vaucluse
|
||||
thing-type.config.meteoalerte.department.department.option.VENDEE = Vendée
|
||||
thing-type.config.meteoalerte.department.department.option.VIENNE = Vienne
|
||||
thing-type.config.meteoalerte.department.department.option.VOSGES = Vosges
|
||||
thing-type.config.meteoalerte.department.department.option.YONNE = Yonne
|
||||
thing-type.config.meteoalerte.department.department.option.YVELINES = Yvelines
|
||||
thing-type.config.meteoalerte.department.refresh.label = Fréquence de rafraichissement
|
||||
thing-type.config.meteoalerte.department.refresh.description = Période d'actualisation des données en minutes.
|
||||
|
||||
# channel types
|
||||
|
||||
channel-type.meteoalerte.avalanches.label = Avalanches
|
||||
channel-type.meteoalerte.avalanches.description = Niveau d'alerte aux avalanches
|
||||
channel-type.meteoalerte.avalanches.state.option.0 = Vert
|
||||
channel-type.meteoalerte.avalanches.state.option.1 = Jaune
|
||||
channel-type.meteoalerte.avalanches.state.option.2 = Orange
|
||||
channel-type.meteoalerte.avalanches.state.option.3 = Rouge
|
||||
channel-type.meteoalerte.canicule.label = Canicule
|
||||
channel-type.meteoalerte.canicule.description = Niveau d'alerte aux fortes températures
|
||||
channel-type.meteoalerte.canicule.state.option.0 = Vert
|
||||
channel-type.meteoalerte.canicule.state.option.1 = Jaune
|
||||
channel-type.meteoalerte.canicule.state.option.2 = Orange
|
||||
channel-type.meteoalerte.canicule.state.option.3 = Rouge
|
||||
channel-type.meteoalerte.comment.label = Commentaire
|
||||
channel-type.meteoalerte.condition-icon.label = Pictogramme
|
||||
channel-type.meteoalerte.condition-icon.description = Pictogramme associé au niveau d'alerte.
|
||||
channel-type.meteoalerte.grand-froid.label = Grand Froid
|
||||
channel-type.meteoalerte.grand-froid.description = Niveau d'alerte aux températures négatives
|
||||
channel-type.meteoalerte.grand-froid.state.option.0 = Vert
|
||||
channel-type.meteoalerte.grand-froid.state.option.1 = Jaune
|
||||
channel-type.meteoalerte.grand-froid.state.option.2 = Orange
|
||||
channel-type.meteoalerte.grand-froid.state.option.3 = Rouge
|
||||
channel-type.meteoalerte.inondation.label = Inondation
|
||||
channel-type.meteoalerte.inondation.description = Niveau d'alerte aux inondations
|
||||
channel-type.meteoalerte.inondation.state.option.0 = Vert
|
||||
channel-type.meteoalerte.inondation.state.option.1 = Jaune
|
||||
channel-type.meteoalerte.inondation.state.option.2 = Orange
|
||||
channel-type.meteoalerte.inondation.state.option.3 = Rouge
|
||||
channel-type.meteoalerte.neige.label = Neige
|
||||
channel-type.meteoalerte.neige.description = Niveau d'alerte aux évènements neigeux
|
||||
channel-type.meteoalerte.neige.state.option.0 = Vert
|
||||
channel-type.meteoalerte.neige.state.option.1 = Jaune
|
||||
channel-type.meteoalerte.neige.state.option.2 = Orange
|
||||
channel-type.meteoalerte.neige.state.option.3 = Rouge
|
||||
channel-type.meteoalerte.orage.label = Orage
|
||||
channel-type.meteoalerte.orage.description = Niveau d'alerte aux évènements orageux
|
||||
channel-type.meteoalerte.orage.state.option.0 = Vert
|
||||
channel-type.meteoalerte.orage.state.option.1 = Jaune
|
||||
channel-type.meteoalerte.orage.state.option.2 = Orange
|
||||
channel-type.meteoalerte.orage.state.option.3 = Rouge
|
||||
channel-type.meteoalerte.pluie-inondation.label = Pluie Inondation
|
||||
channel-type.meteoalerte.pluie-inondation.description = Niveau d'alerte aux inondations causées par les précipitations
|
||||
channel-type.meteoalerte.pluie-inondation.state.option.0 = Vert
|
||||
channel-type.meteoalerte.pluie-inondation.state.option.1 = Jaune
|
||||
channel-type.meteoalerte.pluie-inondation.state.option.2 = Orange
|
||||
channel-type.meteoalerte.pluie-inondation.state.option.3 = Rouge
|
||||
channel-type.meteoalerte.timestamp.label = Heure d'observation
|
||||
channel-type.meteoalerte.vague-submersion.label = Vague Submersion
|
||||
channel-type.meteoalerte.vague-submersion.description = Niveau d'alerte aux vagues submersion
|
||||
channel-type.meteoalerte.vague-submersion.state.option.0 = Vert
|
||||
channel-type.meteoalerte.vague-submersion.state.option.1 = Jaune
|
||||
channel-type.meteoalerte.vague-submersion.state.option.2 = Orange
|
||||
channel-type.meteoalerte.vague-submersion.state.option.3 = Rouge
|
||||
channel-type.meteoalerte.vent.label = Vent
|
||||
channel-type.meteoalerte.vent.description = Niveau d'alerte aux évènements éoliens
|
||||
channel-type.meteoalerte.vent.state.option.0 = Vert
|
||||
channel-type.meteoalerte.vent.state.option.1 = Jaune
|
||||
channel-type.meteoalerte.vent.state.option.2 = Orange
|
||||
channel-type.meteoalerte.vent.state.option.3 = Rouge
|
||||
|
||||
# iconprovider
|
||||
|
||||
iconset.label = Météo Alerte Icons
|
||||
iconset.description = Icons illustrating weather events provided by Météo Alerte
|
@ -1,329 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="meteoalerte"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="department">
|
||||
<label>Alertes Département</label>
|
||||
<description>Fournit les niveaux d'alerte météo pour un département.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="vague-submersion" typeId="vague-submersion"/>
|
||||
<channel id="vent" typeId="vent"/>
|
||||
<channel id="pluie-inondation" typeId="pluie-inondation"/>
|
||||
<channel id="orage" typeId="orage"/>
|
||||
<channel id="inondation" typeId="inondation"/>
|
||||
<channel id="neige" typeId="neige"/>
|
||||
<channel id="canicule" typeId="canicule"/>
|
||||
<channel id="grand-froid" typeId="grand-froid"/>
|
||||
<channel id="avalanches" typeId="avalanches"/>
|
||||
<channel id="vague-submersion-icon" typeId="condition-icon">
|
||||
<label>Icône Vague Submersion</label>
|
||||
</channel>
|
||||
<channel id="vent-icon" typeId="condition-icon">
|
||||
<label>Icône Vent</label>
|
||||
</channel>
|
||||
<channel id="pluie-inondation-icon" typeId="condition-icon">
|
||||
<label>Icône Pluie Inondation</label>
|
||||
</channel>
|
||||
<channel id="orage-icon" typeId="condition-icon">
|
||||
<label>Icône Orage</label>
|
||||
</channel>
|
||||
<channel id="inondation-icon" typeId="condition-icon">
|
||||
<label>Icône Inondation</label>
|
||||
</channel>
|
||||
<channel id="neige-icon" typeId="condition-icon">
|
||||
<label>Icône Neige</label>
|
||||
</channel>
|
||||
<channel id="canicule-icon" typeId="condition-icon">
|
||||
<label>Icône Canicule</label>
|
||||
</channel>
|
||||
<channel id="grand-froid-icon" typeId="condition-icon">
|
||||
<label>Icône Grand Froid</label>
|
||||
</channel>
|
||||
<channel id="avalanches-icon" typeId="condition-icon">
|
||||
<label>Icône Avalanches</label>
|
||||
</channel>
|
||||
<channel id="comment" typeId="comment"/>
|
||||
<channel id="observation-time" typeId="timestamp">
|
||||
<label>Début de validité</label>
|
||||
</channel>
|
||||
<channel id="end-time" typeId="timestamp">
|
||||
<label>Fin de validité</label>
|
||||
</channel>
|
||||
</channels>
|
||||
|
||||
<properties>
|
||||
<property name="thingTypeVersion">1</property>
|
||||
</properties>
|
||||
|
||||
<config-description>
|
||||
<parameter name="department" type="text" required="true">
|
||||
<label>Département</label>
|
||||
<description>Nom du département</description>
|
||||
<options>
|
||||
<option value="AIN">Ain</option>
|
||||
<option value="AISNE">Aisne</option>
|
||||
<option value="ALLIER">Allier</option>
|
||||
<option value="ALPES-DE-HAUTE-PROVENCE">Alpes de Haute Provence</option>
|
||||
<option value="ALPES-MARITIMES">Alpes Maritimes</option>
|
||||
<option value="ARDECHE">Ardèche</option>
|
||||
<option value="ARDENNES">Ardennes</option>
|
||||
<option value="ARIEGE">Ariège</option>
|
||||
<option value="AUBE">Aube</option>
|
||||
<option value="AUDE">Aude</option>
|
||||
<option value="AVEYRON">Aveyron</option>
|
||||
<option value="BAS-RHIN">Bas-Rhin</option>
|
||||
<option value="BOUCHES-DU-RHONE">Bouches du Rhône</option>
|
||||
<option value="CALVADOS">Calvados</option>
|
||||
<option value="CANTAL">Cantal</option>
|
||||
<option value="CHARENTE">Charente</option>
|
||||
<option value="CHARENTE-MARITIME">Charente Maritime</option>
|
||||
<option value="CHER">Cher</option>
|
||||
<option value="CORREZE">Corrèze</option>
|
||||
<option value="CORSE-DU-SUD">Corse du Sud</option>
|
||||
<option value="COTE-D'OR">Côte D'Or</option>
|
||||
<option value="COTES-D'ARMOR">Côtes D'Armor</option>
|
||||
<option value="CREUSE">Creuse</option>
|
||||
<option value="DEUX-SEVRES">Deux Sèvres</option>
|
||||
<option value="DORDOGNE">Dordogne</option>
|
||||
<option value="DOUBS">Doubs</option>
|
||||
<option value="DROME">Drôme</option>
|
||||
<option value="ESSONNE">Essonne</option>
|
||||
<option value="EURE">Eure</option>
|
||||
<option value="EURE-ET-LOIR">Eure et Loir</option>
|
||||
<option value="FINISTERE">Finistère</option>
|
||||
<option value="GARD">Gard</option>
|
||||
<option value="GERS">Gers</option>
|
||||
<option value="GIRONDE">Gironde</option>
|
||||
<option value="HAUT-RHIN">Haut-Rhin</option>
|
||||
<option value="HAUTE-CORSE">Haute Corse</option>
|
||||
<option value="HAUTE-GARONNE">Haute Garonne</option>
|
||||
<option value="HAUTE-LOIRE">Haute Loire</option>
|
||||
<option value="HAUTE-MARNE">Haute Marne</option>
|
||||
<option value="HAUTE-SAONE">Haute Saône</option>
|
||||
<option value="HAUTE-SAVOIE">Haute Savoie</option>
|
||||
<option value="HAUTE-VIENNE">Haute Vienne</option>
|
||||
<option value="HAUTES-ALPES">Hautes Alpes</option>
|
||||
<option value="HAUTES-PYRENEES">Hautes Pyrénées</option>
|
||||
<option value="HAUTS-DE-SEINE">Hauts de Seine</option>
|
||||
<option value="HERAULT">Hérault</option>
|
||||
<option value="ILLE-ET-VILAINE">Ille et Vilaine</option>
|
||||
<option value="INDRE">Indre</option>
|
||||
<option value="INDRE-ET-LOIRE">Indre et Loire</option>
|
||||
<option value="ISERE">Isère</option>
|
||||
<option value="JURA">Jura</option>
|
||||
<option value="LANDES">Landes</option>
|
||||
<option value="LOIR-ET-CHER">Loir et Cher</option>
|
||||
<option value="LOIRE">Loire</option>
|
||||
<option value="LOIRE-ATLANTIQUE">Loire Atlantique</option>
|
||||
<option value="LOIRET">Loiret</option>
|
||||
<option value="LOT">Lot</option>
|
||||
<option value="LOT-ET-GARONNE">Lot et Garonne</option>
|
||||
<option value="LOZERE">Lozère</option>
|
||||
<option value="MAINE-ET-LOIRE">Maine et Loire</option>
|
||||
<option value="MANCHE">Manche</option>
|
||||
<option value="MARNE">Marne</option>
|
||||
<option value="MAYENNE">Mayenne</option>
|
||||
<option value="MEURTHE-ET-MOSELLE">Meurthe et Moselle</option>
|
||||
<option value="MEUSE">Meuse</option>
|
||||
<option value="MORBIHAN">Morbihan</option>
|
||||
<option value="MOSELLE">Moselle</option>
|
||||
<option value="NIEVRE">Nièvre</option>
|
||||
<option value="NORD">Nord</option>
|
||||
<option value="OISE">Oise</option>
|
||||
<option value="ORNE">Orne</option>
|
||||
<option value="PARIS">Paris</option>
|
||||
<option value="PAS-DE-CALAIS">Pas de Calais</option>
|
||||
<option value="PUY-DE-DOME">Puy de Dôme</option>
|
||||
<option value="PYRENEES-ATLANTIQUES">Pyrénées Atlantiques</option>
|
||||
<option value="PYRENEES-ORIENTALES">Pyrénées Orientales</option>
|
||||
<option value="RHONE">Rhône</option>
|
||||
<option value="SAONE-ET-LOIRE">Saône et Loire</option>
|
||||
<option value="SARTHE">Sarthe</option>
|
||||
<option value="SAVOIE">Savoie</option>
|
||||
<option value="SEINE-ET-MARNE">Seine et Marne</option>
|
||||
<option value="SEINE-MARITIME">Seine Maritime</option>
|
||||
<option value="SEINE-SAINT-DENIS">Seine Saint Denis</option>
|
||||
<option value="SOMME">Somme</option>
|
||||
<option value="TARN">Tarn</option>
|
||||
<option value="TARN-ET-GARONNE">Tarn et Garonne</option>
|
||||
<option value="TERRITOIRE DE BELFORT">Territoire de Belfort</option>
|
||||
<option value="VAL-D'OISE">Val D'Oise</option>
|
||||
<option value="VAL-DE-MARNE">Val de Marne</option>
|
||||
<option value="VAR">Var</option>
|
||||
<option value="VAUCLUSE">Vaucluse</option>
|
||||
<option value="VENDEE">Vendée</option>
|
||||
<option value="VIENNE">Vienne</option>
|
||||
<option value="VOSGES">Vosges</option>
|
||||
<option value="YONNE">Yonne</option>
|
||||
<option value="YVELINES">Yvelines</option>
|
||||
</options>
|
||||
<limitToOptions>true</limitToOptions>
|
||||
</parameter>
|
||||
<parameter name="refresh" type="integer" min="1" required="true" unit="min">
|
||||
<label>Fréquence de rafraichissement</label>
|
||||
<description>Période d'actualisation des données en minutes.</description>
|
||||
<default>1440</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
<channel-type id="vent">
|
||||
<item-type>Number</item-type>
|
||||
<label>Vent</label>
|
||||
<description>Niveau d'alerte aux évènements éoliens</description>
|
||||
<category>oh:meteoalerte:vent</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">Vert</option>
|
||||
<option value="1">Jaune</option>
|
||||
<option value="2">Orange</option>
|
||||
<option value="3">Rouge</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="orage">
|
||||
<item-type>Number</item-type>
|
||||
<label>Orage</label>
|
||||
<description>Niveau d'alerte aux évènements orageux</description>
|
||||
<category>oh:meteoalerte:orage</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">Vert</option>
|
||||
<option value="1">Jaune</option>
|
||||
<option value="2">Orange</option>
|
||||
<option value="3">Rouge</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="inondation">
|
||||
<item-type>Number</item-type>
|
||||
<label>Inondation</label>
|
||||
<description>Niveau d'alerte aux inondations</description>
|
||||
<category>oh:meteoalerte:inondation</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">Vert</option>
|
||||
<option value="1">Jaune</option>
|
||||
<option value="2">Orange</option>
|
||||
<option value="3">Rouge</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="neige">
|
||||
<item-type>Number</item-type>
|
||||
<label>Neige</label>
|
||||
<description>Niveau d'alerte aux évènements neigeux</description>
|
||||
<category>oh:meteoalerte:neige</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">Vert</option>
|
||||
<option value="1">Jaune</option>
|
||||
<option value="2">Orange</option>
|
||||
<option value="3">Rouge</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="canicule">
|
||||
<item-type>Number</item-type>
|
||||
<label>Canicule</label>
|
||||
<description>Niveau d'alerte aux fortes températures</description>
|
||||
<category>oh:meteoalerte:canicule</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">Vert</option>
|
||||
<option value="1">Jaune</option>
|
||||
<option value="2">Orange</option>
|
||||
<option value="3">Rouge</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="grand-froid">
|
||||
<item-type>Number</item-type>
|
||||
<label>Grand Froid</label>
|
||||
<description>Niveau d'alerte aux températures négatives</description>
|
||||
<category>oh:meteoalerte:grand-froid</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">Vert</option>
|
||||
<option value="1">Jaune</option>
|
||||
<option value="2">Orange</option>
|
||||
<option value="3">Rouge</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="avalanches">
|
||||
<item-type>Number</item-type>
|
||||
<label>Avalanches</label>
|
||||
<description>Niveau d'alerte aux avalanches</description>
|
||||
<category>oh:meteoalerte:avalanches</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">Vert</option>
|
||||
<option value="1">Jaune</option>
|
||||
<option value="2">Orange</option>
|
||||
<option value="3">Rouge</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="vague-submersion">
|
||||
<item-type>Number</item-type>
|
||||
<label>Vague Submersion</label>
|
||||
<description>Niveau d'alerte aux vagues submersion</description>
|
||||
<category>oh:meteoalerte:vague-submersion</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">Vert</option>
|
||||
<option value="1">Jaune</option>
|
||||
<option value="2">Orange</option>
|
||||
<option value="3">Rouge</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="pluie-inondation">
|
||||
<item-type>Number</item-type>
|
||||
<label>Pluie Inondation</label>
|
||||
<description>Niveau d'alerte aux inondations causées par les précipitations</description>
|
||||
<category>oh:meteoalerte:pluie-inondation</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">Vert</option>
|
||||
<option value="1">Jaune</option>
|
||||
<option value="2">Orange</option>
|
||||
<option value="3">Rouge</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="comment">
|
||||
<item-type>String</item-type>
|
||||
<label>Commentaire</label>
|
||||
<category>text</category>
|
||||
<state readOnly="true" pattern="%s"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="timestamp" advanced="true">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>Heure d'observation</label>
|
||||
<category>time</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="condition-icon">
|
||||
<item-type>Image</item-type>
|
||||
<label>Pictogramme</label>
|
||||
<description>Pictogramme associé au niveau d'alerte.</description>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
</thing:thing-descriptions>
|
@ -1,40 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<update:update-descriptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:update="https://openhab.org/schemas/update-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/update-description/v1.0.0 https://openhab.org/schemas/update-description-1.0.0.xsd">
|
||||
|
||||
<thing-type uid="meteoalerte:department">
|
||||
|
||||
<instruction-set targetVersion="1">
|
||||
<update-channel id="vague-submersion">
|
||||
<type>meteoalerte:vague-submersion</type>
|
||||
</update-channel>
|
||||
<update-channel id="vent">
|
||||
<type>meteoalerte:vent</type>
|
||||
</update-channel>
|
||||
<update-channel id="pluie-inondation">
|
||||
<type>meteoalerte:pluie-inondation</type>
|
||||
</update-channel>
|
||||
<update-channel id="orage">
|
||||
<type>meteoalerte:orage</type>
|
||||
</update-channel>
|
||||
<update-channel id="inondation">
|
||||
<type>meteoalerte:inondation</type>
|
||||
</update-channel>
|
||||
<update-channel id="neige">
|
||||
<type>meteoalerte:neige</type>
|
||||
</update-channel>
|
||||
<update-channel id="canicule">
|
||||
<type>meteoalerte:canicule</type>
|
||||
</update-channel>
|
||||
<update-channel id="grand-froid">
|
||||
<type>meteoalerte:grand-froid</type>
|
||||
</update-channel>
|
||||
<update-channel id="avalanches">
|
||||
<type>meteoalerte:avalanches</type>
|
||||
</update-channel>
|
||||
</instruction-set>
|
||||
|
||||
</thing-type>
|
||||
|
||||
</update:update-descriptions>
|
132
bundles/org.openhab.binding.meteofrance/README.md
Normal file
@ -0,0 +1,132 @@
|
||||
# Meteo France Binding
|
||||
|
||||
This binding provides information made available by Meteo France:
|
||||
|
||||
* Alert level regarding major weather related risk factors (`vigilance` Thing)
|
||||
* Rain intensity forecasts (`rain-forecast`Thing)
|
||||
|
||||
This binding provides its own icon set and provides appropriate static and dynamic SVG icons (see items examples below).
|
||||
|
||||
## Discovery
|
||||
|
||||
Once a bridge with the API key has been created, appropriate departments can be auto discovered based on system location.
|
||||
|
||||
## Binding Configuration
|
||||
|
||||
The binding has no configuration options, all configuration is done at Bridge and Thing level.
|
||||
|
||||
## Bridge Configuration
|
||||
|
||||
The `api` bridge has only one configuration parameter :
|
||||
|
||||
| Parameter | Description |
|
||||
|-----------|-------------------------------------------------------|
|
||||
| apikey | Data-platform token to access the service. Mandatory. |
|
||||
|
||||
To obtain an API key, you must create an account on https://portail-api.meteofrance.fr/web/fr/
|
||||
Inside the API Portal, create an application on "Bulletin Vigilance" and generate they API key (set duration to 0).
|
||||
|
||||
## Thing Configuration
|
||||
|
||||
The `vigilance` thing has these configuration parameters:
|
||||
|
||||
| Parameter | Description |
|
||||
|------------|-------------------------------------------------------------------------|
|
||||
| department | Code of the department (two digits). |
|
||||
| refresh | Refresh interval in minutes. Optional, the default value is 60 minutes. |
|
||||
|
||||
The `rain-forecast` thing has this configuration parameters:
|
||||
|
||||
| Parameter | Description |
|
||||
|-----------|--------------------------------------------------------------|
|
||||
| location | Geo coordinates to be considered by the service. |
|
||||
|
||||
## Channels
|
||||
|
||||
The information that are retrieved is available as these channels:
|
||||
|
||||
| Channel ID | Item Type | Description |
|
||||
|-----------------------|-----------|-----------------------------------------------|
|
||||
| observation-time | DateTime | Date and time of report validity start |
|
||||
| end-time | DateTime | Date and time of report validity end |
|
||||
| comment | String | General comments on alerts for the department |
|
||||
| vent | Number | Wind alert level (*) |
|
||||
| pluie-inondation | Number | Rain alert level (*) |
|
||||
| orage | Number | Storm alert level (*) |
|
||||
| inondation | Number | Flood alert level (*) |
|
||||
| neige | Number | Snow alert level (*) |
|
||||
| canicule | Number | Heat alert level (*) |
|
||||
| grand-froid | Number | Cold alert level (*) |
|
||||
| avalanches | Number | Avalanche alert level (*) |
|
||||
| vague-submersion | Number | Wave submersion alert level (*) |
|
||||
| pluie-inondation-icon | Image | Pictogram of the Rain alert level |
|
||||
| vent-icon | Image | Pictogram of the Wind alert level |
|
||||
| orage-icon | Image | Pictogram of Storm alert level |
|
||||
| inondation-icon | Image | Pictogram of Flood alert level |
|
||||
| neige-icon | Image | Pictogram of Snow alert level |
|
||||
| canicule-icon | Image | Pictogram of Heat alert level |
|
||||
| grand-froid-icon | Image | Pictogram of Cold alert level |
|
||||
| avalanches-icon | Image | Pictogram of Avalanche alert level |
|
||||
| vague-submersion-icon | Image | Pictogram of Wave Submersion alert level |
|
||||
|
||||
(*) Each alert level has an associated color and description:
|
||||
|
||||
| Code | Color | Description |
|
||||
|------|--------|-------------------------------------------|
|
||||
| 0 | Green | No particular vigilance |
|
||||
| 1 | Yellow | Be attentive to the weather situation |
|
||||
| 2 | Orange | Be "very vigilant" in the concerned areas |
|
||||
| 3 | Red | Absolute vigilance required |
|
||||
|
||||
## Provided icon set
|
||||
|
||||
This binding has its own IconProvider and makes available the following list of icons
|
||||
|
||||
| Icon Name | Dynamic | Illustration |
|
||||
|---------------------------------|---------|--------------|
|
||||
| oh:meteofrance:vent | Yes | ![](doc/images/vent.svg) |
|
||||
| oh:meteofrance:pluie-inondation | Yes | ![](doc/images/pluie-inondation.svg) |
|
||||
| oh:meteofrance:orage | Yes | ![](doc/images/orage.svg) |
|
||||
| oh:meteofrance:inondation | Yes | ![](doc/images/inondation.svg) |
|
||||
| oh:meteofrance:neige | Yes | ![](doc/images/neige.svg) |
|
||||
| oh:meteofrance:canicule | Yes | ![](doc/images/canicule.svg) |
|
||||
| oh:meteofrance:grand-froid | Yes | ![](doc/images/grand-froid.svg) |
|
||||
| oh:meteofrance:avalanches | Yes | ![](doc/images/avalanches.svg) |
|
||||
| oh:meteofrance:vague-submersion | Yes | ![](doc/images/vague-submersion.svg) |
|
||||
| oh:meteofrance:meteo_france | No | ![](doc/images/meteo_france.svg) |
|
||||
| oh:meteofrance:intensity | Yes | ![](doc/images/intensity.svg) |
|
||||
|
||||
## Full Example
|
||||
|
||||
meteoalert.things:
|
||||
|
||||
```java
|
||||
Thing meteofrance:department:yvelines @ "MyCity" [department="78", refresh=12]
|
||||
```
|
||||
|
||||
meteoalert.items:
|
||||
|
||||
```java
|
||||
Group gMeteoAlert "Alertes Météo" <oh:meteofrance:meteo_france>
|
||||
String MA_Dept78 "Département 78 [%s]" <text> (gMeteoAlert) {channel="meteofrance:department:yvelines:comment"}
|
||||
Number MA_etat_canicule "Canicule [%s]" <oh:meteofrance:canicule> (gMeteoAlert) {channel="meteofrance:department:yvelines:canicule"}
|
||||
Number MA_etat_grand_froid "Grand Froid [%s]" <oh:meteofrance:grand-froid> (gMeteoAlert) {channel="meteofrance:department:yvelines:grand-froid"}
|
||||
Number MA_etat_pluie_inondation "Pluie-Inondation [%s]" <oh:meteofrance:pluie-inondation> (gMeteoAlert) {channel="meteofrance:department:yvelines:pluie-inondation"}
|
||||
Number MA_etat_neige "Neige [%s]" <oh:meteofrance:neige> (gMeteoAlert) {channel="meteofrance:department:yvelines:neige"}
|
||||
Number MA_etat_vent "Vent [%s]" <oh:meteofrance:vent> (gMeteoAlert) {channel="meteofrance:department:yvelines:vent"}
|
||||
Number MA_etat_inondation "Inondation [%s]" <oh:meteofrance:inondation> (gMeteoAlert) {channel="meteofrance:department:yvelines:inondation"}
|
||||
Number MA_etat_orage "Orage [%s]" <oh:meteofrance:orage> (gMeteoAlert) {channel="meteofrance:department:yvelines:orage"}
|
||||
Number MA_etat_avalanche "Avalanches [%s]" <oh:meteofrance:avalanches> (gMeteoAlert) {channel="meteofrance:department:yvelines:avalanches"}
|
||||
|
||||
Image MA_icon_canicule "Canicule" <oh:meteofrance:canicule> (gMeteoAlert) {channel="meteofrance:department:yvelines:canicule-icon"}
|
||||
Image MA_icon_grand_froid "Grand Froid" <oh:meteofrance:grand-froid> (gMeteoAlert) {channel="meteofrance:department:yvelines:grand-froid-icon"}
|
||||
Image MA_icon_pluie_inondation "Pluie-Inondation" <oh:meteofrance:pluie-inondation> (gMeteoAlert) {channel="meteofrance:department:yvelines:pluie-inondation-icon"}
|
||||
Image MA_icon_neige "Neige" <oh:meteofrance:neige> (gMeteoAlert) {channel="meteofrance:department:yvelines:neige-icon"}
|
||||
Image MA_icon_vent "Vent" <oh:meteofrance:vent> (gMeteoAlert) {channel="meteofrance:department:yvelines:vent-icon"}
|
||||
Image MA_icon_inondation "Inondation" <oh:meteofrance:inondation> (gMeteoAlert) {channel="meteofrance:department:yvelines:inondation-icon"}
|
||||
Image MA_icon_orage "Orage" <oh:meteofrance:orage> (gMeteoAlert) {channel="meteofrance:department:yvelines:orage-icon"}
|
||||
Image MA_icon_avalanche "Avalanche" <oh:meteofrance:avalanches> (gMeteoAlert) {channel="meteofrance:department:yvelines:avalanches-icon"}
|
||||
|
||||
DateTime MA_ObservationTS "Timestamp [%1$tH:%1$tM]" <time> (gMeteoAlert) {channel="meteofrance:department:yvelines:observation-time"}
|
||||
|
||||
```
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 759 B After Width: | Height: | Size: 759 B |
Before Width: | Height: | Size: 802 B After Width: | Height: | Size: 802 B |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
67
bundles/org.openhab.binding.meteofrance/doc/images/intensity.svg
Executable file
@ -0,0 +1,67 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="55" height="63">
|
||||
<defs>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="prefix__e">
|
||||
<feMorphology radius="2" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1" />
|
||||
<feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1" />
|
||||
<feGaussianBlur stdDeviation="1.5" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" in="shadowBlurOuter1" />
|
||||
</filter>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="prefix__g">
|
||||
<feMorphology radius="1.08" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1" />
|
||||
<feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1" />
|
||||
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" in="shadowBlurOuter1" />
|
||||
</filter>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="prefix__i">
|
||||
<feMorphology radius="1.44" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1" />
|
||||
<feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1" />
|
||||
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" in="shadowBlurOuter1" />
|
||||
</filter>
|
||||
<path
|
||||
d="M22.528 23C20.887 23 11 38.241 11 44.803c0 5.174 2.987 10.572 11.528 10.572 7.82 0 11.528-5.346 11.528-10.572C34.056 38.158 24.169 23 22.528 23z"
|
||||
id="prefix__a" />
|
||||
<path
|
||||
d="M10.125 5C9.253 5 4 13.238 4 16.785c0 2.797 1.587 5.715 6.125 5.715 4.155 0 6.125-2.89 6.125-5.715C16.25 13.193 10.997 5 10.125 5z"
|
||||
id="prefix__b" />
|
||||
<path
|
||||
d="M35.313 0C34.129 0 27 11.122 27 15.91c0 3.776 2.154 7.715 8.313 7.715 5.64 0 8.312-3.901 8.312-7.715 0-4.849-7.129-15.91-8.313-15.91z"
|
||||
id="prefix__c" />
|
||||
<mask id="prefix__f" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-2" y="-2" width="27.056"
|
||||
height="36.375">
|
||||
<path fill="#fff" d="M9 21h27.056v36.375H9z" />
|
||||
<use xlink:href="#prefix__a" />
|
||||
</mask>
|
||||
<mask id="prefix__h" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-1.08" y="-1.08"
|
||||
width="14.41" height="19.66">
|
||||
<path fill="#fff" d="M2.92 3.92h14.41v19.66H2.92z" />
|
||||
<use xlink:href="#prefix__b" />
|
||||
</mask>
|
||||
<mask id="prefix__j" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-1.44" y="-1.44"
|
||||
width="19.505" height="26.505">
|
||||
<path fill="#fff" d="M25.56-1.44h19.505v26.505H25.56z" />
|
||||
<use xlink:href="#prefix__c" />
|
||||
</mask>
|
||||
<rect id="prefix__d" x="-8.105" y="28.395" width="67" height="4" rx="2" />
|
||||
</defs>
|
||||
<g transform="translate(2 2)" fill="none" fill-rule="evenodd">
|
||||
<use height="100%" width="100%" xlink:href="#prefix__a" fill="#000" filter="url(#prefix__e)" />
|
||||
<use height="100%" width="100%" xlink:href="#prefix__a" fill="#55a4ff" fill-opacity=".3" />
|
||||
<use height="100%" width="100%" xlink:href="#prefix__a" mask="url(#prefix__f)" stroke="#fff" stroke-width="4" />
|
||||
</g>
|
||||
<g transform="translate(2 2)" fill="none" fill-rule="evenodd">
|
||||
<use height="100%" width="100%" xlink:href="#prefix__b" fill="#000" filter="url(#prefix__g)" />
|
||||
<use height="100%" width="100%" xlink:href="#prefix__b" fill="#55a4ff" fill-opacity=".3" />
|
||||
<use height="100%" width="100%" xlink:href="#prefix__b" mask="url(#prefix__h)" stroke="#fff"
|
||||
stroke-width="2.16" />
|
||||
</g>
|
||||
<g transform="translate(2 2)" fill="none" fill-rule="evenodd">
|
||||
<use height="100%" width="100%" xlink:href="#prefix__c" fill="#000" filter="url(#prefix__i)" />
|
||||
<use height="100%" width="100%" xlink:href="#prefix__c" fill="#55a4ff" fill-opacity=".3" />
|
||||
<use height="100%" width="100%" xlink:href="#prefix__c" mask="url(#prefix__j)" stroke="#fff"
|
||||
stroke-width="2.88" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
@ -10,8 +10,8 @@
|
||||
<version>4.3.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.binding.meteoalerte</artifactId>
|
||||
<artifactId>org.openhab.binding.meteofrance</artifactId>
|
||||
|
||||
<name>openHAB Add-ons :: Bundles :: Meteo Alerte Binding</name>
|
||||
<name>openHAB Add-ons :: Bundles :: Meteo France Binding</name>
|
||||
|
||||
</project>
|
@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.meteoalerte-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<features name="org.openhab.binding.meteofrance-${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-meteoalerte" description="Meteo Alerte Binding" version="${project.version}">
|
||||
<feature name="openhab-binding-meteofrance" description="Meteo France Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.meteoalerte/${project.version}</bundle>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.meteofrance/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link MeteoFranceBindingConstants} class defines common constants, which are
|
||||
* used across the whole binding.
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class MeteoFranceBindingConstants {
|
||||
public static final String BINDING_ID = "meteofrance";
|
||||
public static final String LOCAL = "local";
|
||||
public static final int REQUEST_TIMEOUT_MS = (int) TimeUnit.SECONDS.toMillis(45);
|
||||
|
||||
// List of Bridge Type UIDs
|
||||
public static final ThingTypeUID BRIDGE_TYPE_API = new ThingTypeUID(BINDING_ID, "api");
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
public static final ThingTypeUID THING_TYPE_VIGILANCE = new ThingTypeUID(BINDING_ID, "vigilance");
|
||||
public static final ThingTypeUID THING_TYPE_RAIN_FORECAST = new ThingTypeUID(BINDING_ID, "rain-forecast");
|
||||
|
||||
// List of all Channel IDs
|
||||
|
||||
public static final String OBSERVATION_TIME = "observation-time";
|
||||
public static final String UPDATE_TIME = "update-time";
|
||||
public static final String INTENSITY = "intensity";
|
||||
|
||||
public static final String END_TIME = "end-time";
|
||||
public static final String COMMENT = "comment";
|
||||
|
||||
public static final Set<ThingTypeUID> DISCOVERABLE_THING_TYPES_UIDS = Set.of(THING_TYPE_VIGILANCE,
|
||||
THING_TYPE_RAIN_FORECAST);
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Stream
|
||||
.of(Set.of(BRIDGE_TYPE_API), DISCOVERABLE_THING_TYPES_UIDS).flatMap(Set::stream)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* An exception that occurred while communicating with Meteo France API server or related processes.
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class MeteoFranceException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 7613161188837438233L;
|
||||
|
||||
public MeteoFranceException(String format, Object... args) {
|
||||
super(format.formatted(args));
|
||||
}
|
||||
|
||||
public MeteoFranceException(Exception e, String format, Object... args) {
|
||||
super(format.formatted(args), e);
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal;
|
||||
|
||||
import static org.openhab.binding.meteofrance.internal.MeteoFranceBindingConstants.*;
|
||||
|
||||
import java.time.ZoneId;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.meteofrance.internal.db.DepartmentDbService;
|
||||
import org.openhab.binding.meteofrance.internal.deserialization.MeteoFranceDeserializer;
|
||||
import org.openhab.binding.meteofrance.internal.handler.MeteoFranceBridgeHandler;
|
||||
import org.openhab.binding.meteofrance.internal.handler.RainForecastHandler;
|
||||
import org.openhab.binding.meteofrance.internal.handler.VigilanceHandler;
|
||||
import org.openhab.core.i18n.LocationProvider;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
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 MeteoFranceHandlerFactory} is responsible for creating things and thing handlers.
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@Component(service = ThingHandlerFactory.class)
|
||||
@NonNullByDefault
|
||||
public class MeteoFranceHandlerFactory extends BaseThingHandlerFactory {
|
||||
private final MeteoFranceIconProvider iconProvider;
|
||||
private final MeteoFranceDeserializer deserializer;
|
||||
private final ZoneId zoneId;
|
||||
|
||||
@Activate
|
||||
public MeteoFranceHandlerFactory(final @Reference TimeZoneProvider timeZoneProvider,
|
||||
final @Reference LocationProvider locationProvider, final @Reference DepartmentDbService dbService,
|
||||
final @Reference MeteoFranceIconProvider iconProvider,
|
||||
final @Reference MeteoFranceDeserializer deserializer) {
|
||||
this.iconProvider = iconProvider;
|
||||
this.deserializer = deserializer;
|
||||
this.zoneId = timeZoneProvider.getTimeZone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
return BRIDGE_TYPE_API.equals(thingTypeUID) ? new MeteoFranceBridgeHandler((Bridge) thing, deserializer)
|
||||
: THING_TYPE_VIGILANCE.equals(thingTypeUID) ? new VigilanceHandler(thing, zoneId, iconProvider)
|
||||
: THING_TYPE_RAIN_FORECAST.equals(thingTypeUID) ? new RainForecastHandler(thing, zoneId) : null;
|
||||
}
|
||||
}
|
@ -10,21 +10,24 @@
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.meteoalerte.internal;
|
||||
package org.openhab.binding.meteofrance.internal;
|
||||
|
||||
import static org.openhab.binding.meteoalerte.internal.MeteoAlerteBindingConstants.*;
|
||||
import static org.openhab.binding.meteofrance.internal.MeteoFranceBindingConstants.*;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.meteoalerte.internal.json.ResponseFieldDTO.AlertLevel;
|
||||
import org.openhab.binding.meteofrance.internal.dto.Hazard;
|
||||
import org.openhab.binding.meteofrance.internal.dto.Risk;
|
||||
import org.openhab.core.i18n.TranslationProvider;
|
||||
import org.openhab.core.ui.icon.IconProvider;
|
||||
import org.openhab.core.ui.icon.IconSet;
|
||||
@ -37,24 +40,27 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link MeteoAlertIconProvider} is the class providing binding related icons.
|
||||
* The {@link MeteoFranceIconProvider} is the class providing binding related icons.
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@Component(service = { IconProvider.class, MeteoAlertIconProvider.class })
|
||||
@Component(service = { IconProvider.class, MeteoFranceIconProvider.class })
|
||||
@NonNullByDefault
|
||||
public class MeteoAlertIconProvider implements IconProvider {
|
||||
private static final String DEFAULT_LABEL = "Météo Alerte Icons";
|
||||
private static final String DEFAULT_DESCRIPTION = "Icons illustrating weather events provided by Météo Alerte";
|
||||
private static final Set<String> ICONS = Set.of(WAVE, AVALANCHE, HEAT, FREEZE, FLOOD, SNOW, STORM, RAIN, WIND,
|
||||
"meteo_france");
|
||||
public class MeteoFranceIconProvider implements IconProvider {
|
||||
private static final String NEUTRAL_COLOR = "#3d3c3c";
|
||||
private static final String DEFAULT_LABEL = "Météo France Icons";
|
||||
private static final String DEFAULT_DESCRIPTION = "Icons illustrating weather alerts provided by Météo France";
|
||||
private static final List<String> HAZARD_ICONS = Hazard.AS_SET.stream().filter(Hazard::isChannel)
|
||||
.map(h -> h.channelName).toList();
|
||||
private static final List<String> ICONS = Stream.concat(Stream.of("meteo_france", INTENSITY), HAZARD_ICONS.stream())
|
||||
.toList();
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(MeteoAlertIconProvider.class);
|
||||
private final Logger logger = LoggerFactory.getLogger(MeteoFranceIconProvider.class);
|
||||
private final BundleContext context;
|
||||
private final TranslationProvider i18nProvider;
|
||||
|
||||
@Activate
|
||||
public MeteoAlertIconProvider(final BundleContext context, final @Reference TranslationProvider i18nProvider) {
|
||||
public MeteoFranceIconProvider(final BundleContext context, final @Reference TranslationProvider i18nProvider) {
|
||||
this.context = context;
|
||||
this.i18nProvider = i18nProvider;
|
||||
}
|
||||
@ -83,7 +89,7 @@ public class MeteoAlertIconProvider implements IconProvider {
|
||||
|
||||
@Override
|
||||
public @Nullable Integer hasIcon(String category, String iconSetId, Format format) {
|
||||
return ICONS.contains(category) && iconSetId.equals(BINDING_ID) && format == Format.SVG ? 0 : null;
|
||||
return Format.SVG.equals(format) && iconSetId.equals(BINDING_ID) && ICONS.contains(category) ? 0 : null;
|
||||
}
|
||||
|
||||
public @Nullable InputStream getIcon(String category, String state) {
|
||||
@ -92,17 +98,25 @@ public class MeteoAlertIconProvider implements IconProvider {
|
||||
|
||||
@Override
|
||||
public @Nullable InputStream getIcon(String category, String iconSetId, @Nullable String state, Format format) {
|
||||
String icon = getResource(category);
|
||||
String iconName = category;
|
||||
if (INTENSITY.equals(category) && state != null) {
|
||||
String localState = "on".equalsIgnoreCase(state) ? "3" : "off".equalsIgnoreCase(state) ? "0" : state;
|
||||
try {
|
||||
iconName = "%s-%d".formatted(category, Double.valueOf(localState).intValue());
|
||||
} catch (NumberFormatException e) {
|
||||
logger.debug("Unable to parse {} to a numeric value", state);
|
||||
}
|
||||
}
|
||||
String icon = getResource(iconName);
|
||||
if (icon.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (state != null) {
|
||||
if (state != null && HAZARD_ICONS.contains(category)) {
|
||||
try {
|
||||
Integer ordinal = Integer.valueOf(state);
|
||||
AlertLevel alertLevel = ordinal < AlertLevel.values().length ? AlertLevel.values()[ordinal]
|
||||
: AlertLevel.UNKNOWN;
|
||||
icon = icon.replaceAll(AlertLevel.UNKNOWN.color, alertLevel.color);
|
||||
int ordinal = Integer.valueOf(state);
|
||||
Risk alertLevel = ordinal < Risk.values().length ? Risk.values()[ordinal] : Risk.UNKNOWN;
|
||||
icon = icon.replaceAll(NEUTRAL_COLOR, alertLevel.rgbColor);
|
||||
} catch (NumberFormatException e) {
|
||||
logger.debug("{} is not a valid DecimalType", state);
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal.config;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link BridgeConfiguration} is the class used to match the bridge configuration.
|
||||
*
|
||||
* @author Gaël L"hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class BridgeConfiguration {
|
||||
public String apikey = "";
|
||||
}
|
@ -10,18 +10,19 @@
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.meteoalerte.internal;
|
||||
package org.openhab.binding.meteofrance.internal.config;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link MeteoAlerteConfiguration} is the class used to match the
|
||||
* The {@link DepartmentConfiguration} is the class used to match the
|
||||
* thing configuration.
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class MeteoAlerteConfiguration {
|
||||
public class DepartmentConfiguration {
|
||||
public static final String DEPARTMENT = "department";
|
||||
public String department = "";
|
||||
public int refresh = 1440;
|
||||
public int refresh = 60;
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal.config;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link ForecastConfiguration} is the class used to match the rain forecast thing configuration.
|
||||
*
|
||||
* @author Gaël L"hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ForecastConfiguration {
|
||||
public static final String LOCATION = "location";
|
||||
|
||||
public String location = "";
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal.db;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.library.types.PointType;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.FieldNamingPolicy;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonIOException;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
/**
|
||||
* The {@link DepartmentDbService} makes available a list of known French Metropolitan departments.
|
||||
*
|
||||
* @author Gaël L'hopital - Initial Contribution
|
||||
*/
|
||||
|
||||
@Component(service = DepartmentDbService.class)
|
||||
@NonNullByDefault
|
||||
public class DepartmentDbService {
|
||||
private final Logger logger = LoggerFactory.getLogger(DepartmentDbService.class);
|
||||
private final List<Department> departments = new ArrayList<>();
|
||||
|
||||
public record Department(String id, String name, double northestLat, double southestLat, double eastestLon,
|
||||
double westestLon) {
|
||||
}
|
||||
|
||||
@Activate
|
||||
public DepartmentDbService() {
|
||||
try (InputStream is = Thread.currentThread().getContextClassLoader()
|
||||
.getResourceAsStream("/db/departments.json");
|
||||
Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) {
|
||||
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
|
||||
departments.addAll(Arrays.asList(gson.fromJson(reader, Department[].class)));
|
||||
logger.debug("Successfully loaded {} departments", departments.size());
|
||||
} catch (IOException | JsonSyntaxException | JsonIOException e) {
|
||||
logger.warn("Unable to load departments list: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public List<Department> getBounding(PointType location) {
|
||||
double latitude = location.getLatitude().doubleValue();
|
||||
double longitude = location.getLongitude().doubleValue();
|
||||
return departments.stream().filter(dep -> dep.northestLat >= latitude && dep.southestLat <= latitude
|
||||
&& dep.westestLon <= longitude && dep.eastestLon >= longitude).toList();
|
||||
}
|
||||
|
||||
public @Nullable Department getDept(String deptId) {
|
||||
return departments.stream().filter(dep -> dep.id.equalsIgnoreCase(deptId)).findFirst().orElse(null);
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal.deserialization;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.meteofrance.internal.MeteoFranceException;
|
||||
import org.openhab.binding.meteofrance.internal.dto.MeteoFrance.Periods;
|
||||
import org.openhab.binding.meteofrance.internal.dto.MeteoFrance.Timelaps;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
import com.google.gson.FieldNamingPolicy;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
/**
|
||||
* The {@link MeteoFranceDeserializer} is responsible to instantiate suitable Gson (de)serializer
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(service = MeteoFranceDeserializer.class)
|
||||
public class MeteoFranceDeserializer {
|
||||
private final Gson gson;
|
||||
|
||||
@Activate
|
||||
public MeteoFranceDeserializer(final @Reference TimeZoneProvider timeZoneProvider) {
|
||||
gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
|
||||
.registerTypeAdapterFactory(new StrictEnumTypeAdapterFactory())
|
||||
.registerTypeAdapter(Periods.class, new PeriodsDeserializer())
|
||||
.registerTypeAdapter(Timelaps.class, new TimelapsDeserializer())
|
||||
.registerTypeAdapter(ZonedDateTime.class,
|
||||
(JsonDeserializer<ZonedDateTime>) (json, type, context) -> ZonedDateTime
|
||||
.parse(json.getAsJsonPrimitive().getAsString())
|
||||
.withZoneSameInstant(timeZoneProvider.getTimeZone()))
|
||||
.create();
|
||||
}
|
||||
|
||||
public <T> T deserialize(Class<T> clazz, String json) throws MeteoFranceException {
|
||||
try {
|
||||
@Nullable
|
||||
T result = gson.fromJson(json, clazz);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
throw new MeteoFranceException("Deserialization of '%s' resulted in null value", json);
|
||||
} catch (JsonSyntaxException e) {
|
||||
throw new MeteoFranceException(e, "Unexpected error deserializing '%s'", json);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal.deserialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.meteofrance.internal.dto.MeteoFrance.Period;
|
||||
import org.openhab.binding.meteofrance.internal.dto.MeteoFrance.Periods;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
/**
|
||||
* The {@link PeriodsDeserializer} is a specialized deserializer aimed to transform
|
||||
* a list of `Period` into a map identified by the Period Term.
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
class PeriodsDeserializer implements JsonDeserializer<Periods> {
|
||||
@Override
|
||||
public @NonNull Periods deserialize(JsonElement json, Type clazz, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
Periods result = new Periods();
|
||||
if (json instanceof JsonArray jsonArray) {
|
||||
jsonArray.forEach(item -> {
|
||||
Period period = context.deserialize(item, Period.class);
|
||||
result.put(period.echeance(), period);
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal.deserialization;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
/**
|
||||
* Enforces a fallback to UNKNOWN when deserializing enum types, marked as @NonNull whereas they were valued
|
||||
* to null if the appropriate value is absent.
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
class StrictEnumTypeAdapterFactory implements TypeAdapterFactory {
|
||||
private static final StringReader UNKNOWN = new StringReader("\"UNKNOWN\"");
|
||||
|
||||
@Override
|
||||
public @Nullable <T> TypeAdapter<T> create(@NonNullByDefault({}) Gson gson,
|
||||
@NonNullByDefault({}) TypeToken<T> type) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<T> rawType = (Class<T>) type.getRawType();
|
||||
return rawType.isEnum() ? newStrictEnumAdapter(gson.getDelegateAdapter(this, type)) : null;
|
||||
}
|
||||
|
||||
private <T> TypeAdapter<T> newStrictEnumAdapter(@NonNullByDefault({}) TypeAdapter<T> delegateAdapter) {
|
||||
return new TypeAdapter<>() {
|
||||
@Override
|
||||
public void write(JsonWriter out, @Nullable T value) throws IOException {
|
||||
delegateAdapter.write(out, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable T read(JsonReader in) throws IOException {
|
||||
JsonReader delegateReader = new JsonReader(new StringReader('"' + in.nextString() + '"'));
|
||||
@Nullable
|
||||
T value = delegateAdapter.read(delegateReader);
|
||||
delegateReader.close();
|
||||
if (value == null) {
|
||||
UNKNOWN.reset();
|
||||
value = delegateAdapter.read(new JsonReader(UNKNOWN));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal.deserialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.meteofrance.internal.dto.MeteoFrance.DomainId;
|
||||
import org.openhab.binding.meteofrance.internal.dto.MeteoFrance.Timelaps;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
/**
|
||||
* The {@link TimelapsDeserializer} is a specialized deserializer aimed to transform
|
||||
* a list of `Period` into a map identified by the Period Term.
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
class TimelapsDeserializer implements JsonDeserializer<Timelaps> {
|
||||
@Override
|
||||
public @NonNull Timelaps deserialize(JsonElement json, Type clazz, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
Timelaps result = new Timelaps();
|
||||
JsonElement domains = json.getAsJsonObject().get("domain_ids");
|
||||
if (domains instanceof JsonArray jsonArray) {
|
||||
jsonArray.forEach(item -> {
|
||||
DomainId domainId = context.deserialize(item, DomainId.class);
|
||||
result.put(domainId.domain(), domainId);
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal.discovery;
|
||||
|
||||
import static org.openhab.binding.meteofrance.internal.MeteoFranceBindingConstants.*;
|
||||
import static org.openhab.binding.meteofrance.internal.config.ForecastConfiguration.LOCATION;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.meteofrance.internal.config.DepartmentConfiguration;
|
||||
import org.openhab.binding.meteofrance.internal.db.DepartmentDbService;
|
||||
import org.openhab.binding.meteofrance.internal.db.DepartmentDbService.Department;
|
||||
import org.openhab.binding.meteofrance.internal.handler.MeteoFranceBridgeHandler;
|
||||
import org.openhab.core.config.discovery.AbstractThingHandlerDiscoveryService;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.i18n.LocaleProvider;
|
||||
import org.openhab.core.i18n.LocationProvider;
|
||||
import org.openhab.core.i18n.TranslationProvider;
|
||||
import org.openhab.core.library.types.PointType;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.binding.ThingHandlerService;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link MeteoFranceDiscoveryService} discovers departments on the configured location.
|
||||
*
|
||||
* @author Gaël L'hopital - Initial Contribution
|
||||
*/
|
||||
@Component(service = ThingHandlerService.class)
|
||||
@NonNullByDefault
|
||||
public class MeteoFranceDiscoveryService extends AbstractThingHandlerDiscoveryService<MeteoFranceBridgeHandler> {
|
||||
private static final int DISCOVER_TIMEOUT_SECONDS = 2;
|
||||
private @NonNullByDefault({}) LocationProvider locationProvider;
|
||||
private @NonNullByDefault({}) DepartmentDbService dbService;
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(MeteoFranceDiscoveryService.class);
|
||||
|
||||
public MeteoFranceDiscoveryService() {
|
||||
super(MeteoFranceBridgeHandler.class, DISCOVERABLE_THING_TYPES_UIDS, DISCOVER_TIMEOUT_SECONDS);
|
||||
}
|
||||
|
||||
@Reference(unbind = "-")
|
||||
public void bindTranslationProvider(TranslationProvider translationProvider) {
|
||||
this.i18nProvider = translationProvider;
|
||||
}
|
||||
|
||||
@Reference(unbind = "-")
|
||||
public void bindLocaleProvider(LocaleProvider localeProvider) {
|
||||
this.localeProvider = localeProvider;
|
||||
}
|
||||
|
||||
@Reference(unbind = "-")
|
||||
public void bindLocationProvider(LocationProvider locationProvider) {
|
||||
this.locationProvider = locationProvider;
|
||||
}
|
||||
|
||||
@Reference(unbind = "-")
|
||||
public void bindDepartmentDbService(DepartmentDbService dbService) {
|
||||
this.dbService = dbService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startScan() {
|
||||
logger.debug("Starting Meteo France department discovery scan");
|
||||
|
||||
LocationProvider localLocation = locationProvider;
|
||||
PointType location = localLocation != null ? localLocation.getLocation() : null;
|
||||
if (location == null) {
|
||||
logger.debug("LocationProvider.getLocation() is not set -> Will not provide any discovery results");
|
||||
return;
|
||||
}
|
||||
|
||||
createDepartmentResults(location);
|
||||
createForecastResults(location);
|
||||
}
|
||||
|
||||
private void createForecastResults(PointType location) {
|
||||
thingDiscovered(DiscoveryResultBuilder.create(new ThingUID(THING_TYPE_RAIN_FORECAST, LOCAL))
|
||||
.withLabel("@text/discovery.meteofrance.rain-forecast.local.label")
|
||||
.withProperty(LOCATION, location.toString()).withRepresentationProperty(LOCATION).build());
|
||||
}
|
||||
|
||||
private void createDepartmentResults(PointType serverLocation) {
|
||||
List<Department> candidates = dbService.getBounding(serverLocation);
|
||||
ThingUID bridgeUID = thingHandler.getThing().getUID();
|
||||
if (!candidates.isEmpty()) {
|
||||
candidates.forEach(dep -> thingDiscovered(
|
||||
DiscoveryResultBuilder.create(new ThingUID(THING_TYPE_VIGILANCE, bridgeUID, dep.id()))//
|
||||
.withLabel("Vigilance Météo: %s".formatted(dep.name())) //
|
||||
.withProperty(DepartmentConfiguration.DEPARTMENT, dep.id()) //
|
||||
.withRepresentationProperty(DepartmentConfiguration.DEPARTMENT) //
|
||||
.withBridge(bridgeUID).build()));
|
||||
} else {
|
||||
logger.info("No department could be discovered matching server location");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal.dto;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum BlocType {
|
||||
SITUATION, // Situation Actuelle
|
||||
INCERTITUDE, // Prévisibilité et incertitudes
|
||||
QUALIFICATION, // Qualification
|
||||
EVOLUTION, // Évolution prévue
|
||||
UNKNOWN // Inconnue
|
||||
}
|
@ -0,0 +1,269 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal.dto;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum Domain {
|
||||
@SerializedName("FRA")
|
||||
FRANCE("France"),
|
||||
|
||||
@SerializedName("ZDF_EST")
|
||||
ZDF_EST("Défense Est"),
|
||||
@SerializedName("ZDF_PARIS")
|
||||
ZDF_PARIS("Défense Paris"),
|
||||
@SerializedName("ZDF_NORD")
|
||||
ZDF_NORD("Défense Nord"),
|
||||
@SerializedName("ZDF_SUD_EST")
|
||||
ZDF_SUD_EST("Défense Sud-Est"),
|
||||
@SerializedName("ZDF_SUD_OUEST")
|
||||
ZDF_SUD_OUEST("Défense Sud-Ouest"),
|
||||
@SerializedName("ZDF_SUD")
|
||||
ZDF_SUD("Défense Sud"),
|
||||
@SerializedName("ZDF_OUEST")
|
||||
ZDF_OUEST("Défense Ouest"),
|
||||
|
||||
@SerializedName("01")
|
||||
AIN("Ain"),
|
||||
@SerializedName("02")
|
||||
AISNE("Aisne"),
|
||||
@SerializedName("03")
|
||||
ALLIER("Allier"),
|
||||
@SerializedName("04")
|
||||
ALPES_DE_HAUTE_PROVENCE("Alpes-de-Haute-Provence"),
|
||||
@SerializedName("05")
|
||||
HAUTES_ALPES("Hautes-Alpes"),
|
||||
@SerializedName("06")
|
||||
ALPES_MARITIMES("Alpes-Maritimes"),
|
||||
@SerializedName("07")
|
||||
ARDECHE("Ardèche"),
|
||||
@SerializedName("08")
|
||||
ARDENNES("Ardennes"),
|
||||
@SerializedName("09")
|
||||
ARIEGE("Ariège"),
|
||||
@SerializedName("10")
|
||||
AUBE("Aube"),
|
||||
@SerializedName("11")
|
||||
AUDE("Aude"),
|
||||
@SerializedName("12")
|
||||
AVEYRON("Aveyron"),
|
||||
@SerializedName("13")
|
||||
BOUCHES_DU_RHONE("Bouches-du-Rhône"),
|
||||
@SerializedName("14")
|
||||
CALVADOS("Calvados"),
|
||||
@SerializedName("15")
|
||||
CANTAL("Cantal"),
|
||||
@SerializedName("16")
|
||||
CHARENTE("Charente"),
|
||||
@SerializedName("17")
|
||||
CHARENTE_MARITIME("Charente-Maritime"),
|
||||
@SerializedName("18")
|
||||
CHER("Cher"),
|
||||
@SerializedName("19")
|
||||
CORREZE("Corrèze"),
|
||||
@SerializedName("2A")
|
||||
CORSE_DU_SUD("Corse-du-Sud"),
|
||||
@SerializedName("2B")
|
||||
HAUTE_CORSE("Haute-Corse"),
|
||||
@SerializedName("21")
|
||||
COTE_D_OR("Côte-d'Or"),
|
||||
@SerializedName("22")
|
||||
COTES_D_ARMOR("Côtes-d'Armor"),
|
||||
@SerializedName("23")
|
||||
CREUSE("Creuse"),
|
||||
@SerializedName("24")
|
||||
DORDOGNE("Dordogne"),
|
||||
@SerializedName("25")
|
||||
DOUBS("Doubs"),
|
||||
@SerializedName("26")
|
||||
DROME("Drôme"),
|
||||
@SerializedName("27")
|
||||
EURE("Eure"),
|
||||
@SerializedName("28")
|
||||
EURE_ET_LOIR("Eure-et-Loir"),
|
||||
@SerializedName("29")
|
||||
FINISTERE("Finistère"),
|
||||
@SerializedName("30")
|
||||
GARD("Gard"),
|
||||
@SerializedName("31")
|
||||
HAUTE_GARONNE("Haute-Garonne"),
|
||||
@SerializedName("32")
|
||||
GERS("Gers"),
|
||||
@SerializedName("33")
|
||||
GIRONDE("Gironde"),
|
||||
@SerializedName("34")
|
||||
HERAULT("Hérault"),
|
||||
@SerializedName("35")
|
||||
ILLE_ET_VILAINE("Ille-et-Vilaine"),
|
||||
@SerializedName("36")
|
||||
INDRE("Indre"),
|
||||
@SerializedName("37")
|
||||
INDRE_ET_LOIRE("Indre-et-Loire"),
|
||||
@SerializedName("38")
|
||||
ISERE("Isère"),
|
||||
@SerializedName("39")
|
||||
JURA("Jura"),
|
||||
@SerializedName("40")
|
||||
LANDES("Landes"),
|
||||
@SerializedName("41")
|
||||
LOIR_ET_CHER("Loir-et-Cher"),
|
||||
@SerializedName("42")
|
||||
LOIRE("Loire"),
|
||||
@SerializedName("43")
|
||||
HAUTE_LOIRE("Haute-Loire"),
|
||||
@SerializedName("44")
|
||||
LOIRE_ATLANTIQUE("Loire-Atlantique"),
|
||||
@SerializedName("45")
|
||||
LOIRET("Loiret"),
|
||||
@SerializedName("46")
|
||||
LOT("Lot"),
|
||||
@SerializedName("47")
|
||||
LOT_ET_GARONNE("Lot-et-Garonne"),
|
||||
@SerializedName("48")
|
||||
LOZERE("Lozère"),
|
||||
@SerializedName("49")
|
||||
MAINE_ET_LOIRE("Maine-et-Loire"),
|
||||
@SerializedName("50")
|
||||
MANCHE("Manche"),
|
||||
@SerializedName("51")
|
||||
MARNE("Marne"),
|
||||
@SerializedName("52")
|
||||
HAUTE_MARNE("Haute-Marne"),
|
||||
@SerializedName("53")
|
||||
MAYENNE("Mayenne"),
|
||||
@SerializedName("54")
|
||||
MEURTHE_ET_MOSELLE("Meurthe-et-Moselle"),
|
||||
@SerializedName("55")
|
||||
MEUSE("Meuse"),
|
||||
@SerializedName("56")
|
||||
MORBIHAN("Morbihan"),
|
||||
@SerializedName("57")
|
||||
MOSELLE("Moselle"),
|
||||
@SerializedName("58")
|
||||
NIEVRE("Nièvre"),
|
||||
@SerializedName("59")
|
||||
NORD("Nord"),
|
||||
@SerializedName("60")
|
||||
OISE("Oise"),
|
||||
@SerializedName("61")
|
||||
ORNE("Orne"),
|
||||
@SerializedName("62")
|
||||
PAS_DE_CALAIS("Pas-de-Calais"),
|
||||
@SerializedName("63")
|
||||
PUY_DE_DOME("Puy-de-Dôme"),
|
||||
@SerializedName("64")
|
||||
PYRENEES_ATLANTIQUES("Pyrénées-Atlantiques"),
|
||||
@SerializedName("65")
|
||||
HAUTES_PYRENEES("Hautes-Pyrénées"),
|
||||
@SerializedName("66")
|
||||
PYRENEES_ORIENTALES("Pyrénées-Orientales"),
|
||||
@SerializedName("67")
|
||||
BAS_RHIN("Bas-Rhin"),
|
||||
@SerializedName("68")
|
||||
HAUT_RHIN("Haut-Rhin"),
|
||||
@SerializedName("69")
|
||||
RHONE("Rhône"),
|
||||
@SerializedName("70")
|
||||
HAUTE_SAONE("Haute-Saône"),
|
||||
@SerializedName("71")
|
||||
SAONE_ET_LOIRE("Saône-et-Loire"),
|
||||
@SerializedName("72")
|
||||
SARTHE("Sarthe"),
|
||||
@SerializedName("73")
|
||||
SAVOIE("Savoie"),
|
||||
@SerializedName("74")
|
||||
HAUTE_SAVOIE("Haute-Savoie"),
|
||||
@SerializedName("75")
|
||||
PARIS("Paris"),
|
||||
@SerializedName("76")
|
||||
SEINE_MARITIME("Seine-Maritime"),
|
||||
@SerializedName("77")
|
||||
SEINE_ET_MARNE("Seine-et-Marne"),
|
||||
@SerializedName("78")
|
||||
YVELINES("Yvelines"),
|
||||
@SerializedName("79")
|
||||
DEUX_SEVRES("Deux-Sèvres"),
|
||||
@SerializedName("80")
|
||||
SOMME("Somme"),
|
||||
@SerializedName("81")
|
||||
TARN("Tarn"),
|
||||
@SerializedName("82")
|
||||
TARN_ET_GARONNE("Tarn-et-Garonne"),
|
||||
@SerializedName("83")
|
||||
VAR("Var"),
|
||||
@SerializedName("84")
|
||||
VAUCLUSE("Vaucluse"),
|
||||
@SerializedName("85")
|
||||
VENDEE("Vendée"),
|
||||
@SerializedName("86")
|
||||
VIENNE("Vienne"),
|
||||
@SerializedName("87")
|
||||
HAUTE_VIENNE("Haute-Vienne"),
|
||||
@SerializedName("88")
|
||||
VOSGES("Vosges"),
|
||||
@SerializedName("89")
|
||||
YONNE("Yonne"),
|
||||
@SerializedName("90")
|
||||
TERRITOIRE_DE_BELFORT("Territoire de Belfort"),
|
||||
@SerializedName("91")
|
||||
ESSONNE("Essonne"),
|
||||
@SerializedName("92")
|
||||
HAUTS_DE_SEINE("Hauts-de-Seine"),
|
||||
@SerializedName("93")
|
||||
SEINE_SAINT_DENIS("Seine-Saint-Denis"),
|
||||
@SerializedName("94")
|
||||
VAL_DE_MARNE("Val-de-Marne"),
|
||||
@SerializedName("95")
|
||||
VAL_D_OISE("Val-d'Oise"),
|
||||
@SerializedName("99")
|
||||
ANDORRE("Andorre"),
|
||||
|
||||
UNKNOWN("Unknown");
|
||||
|
||||
public final String description;
|
||||
private final @Nullable String apiId;
|
||||
|
||||
Domain(String description) {
|
||||
this.description = description;
|
||||
this.apiId = getSerializedName();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String getSerializedName() {
|
||||
try {
|
||||
Field f = getClass().getField(this.name());
|
||||
SerializedName a = f.getAnnotation(SerializedName.class);
|
||||
if (a != null) {
|
||||
return a.value();
|
||||
}
|
||||
} catch (NoSuchFieldException ignored) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Domain getByApiId(String searched) {
|
||||
return Objects.requireNonNull(EnumSet.allOf(Domain.class).stream().filter(dom -> searched.equals(dom.apiId))
|
||||
.findFirst().orElse(UNKNOWN));
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal.dto;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum Hazard {
|
||||
@SerializedName("1")
|
||||
VENT("vent"),
|
||||
@SerializedName("2")
|
||||
PLUIE("pluie-inondation"),
|
||||
@SerializedName("3")
|
||||
ORAGES("orage"),
|
||||
@SerializedName("4")
|
||||
CRUES("inondation"),
|
||||
@SerializedName("5")
|
||||
NEIGE_VERGLAS("neige"),
|
||||
@SerializedName("6")
|
||||
CANICULE("canicule"),
|
||||
@SerializedName("7")
|
||||
GRAND_FROID("grand-froid"),
|
||||
@SerializedName("8")
|
||||
AVALANCHES("avalanches"),
|
||||
@SerializedName("9")
|
||||
VAGUES_SUBMERSION("vague-submersion"),
|
||||
ALL(""),
|
||||
UNKNOWN("");
|
||||
|
||||
public static final EnumSet<Hazard> AS_SET = EnumSet.allOf(Hazard.class);
|
||||
|
||||
public final String channelName;
|
||||
|
||||
Hazard(String channelName) {
|
||||
this.channelName = channelName;
|
||||
}
|
||||
|
||||
public boolean isChannel() {
|
||||
return !channelName.isEmpty();
|
||||
}
|
||||
}
|
@ -0,0 +1,174 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal.dto;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class MeteoFrance {
|
||||
public record VigilanceEnCours(//
|
||||
@Nullable Product product, //
|
||||
@Nullable Meta meta, //
|
||||
int code, // error code, 0 if all went well
|
||||
@Nullable String message, // error message when code != 0
|
||||
@Nullable String detail) {
|
||||
}
|
||||
|
||||
public record Meta(//
|
||||
String snapshotId, // identifiant du snapshot de la saisie validée
|
||||
ZonedDateTime productDatetime, // date/heure de diffusion du produit
|
||||
ZonedDateTime generationTimestamp) { // date/heure de début de validité du produit
|
||||
}
|
||||
|
||||
public record Product(//
|
||||
String warningType, // "vigilance" - produit de la famille Vigilance
|
||||
String typeCdp, // "cdp_textes" - nom générique du produit
|
||||
String versionVigilance, // "V6" - Version du système développé
|
||||
String versionCdp, // "x.y.z" - version du format pour pouvoir gérer d'anciens jeux de données
|
||||
ZonedDateTime updateTime, // "AAAA-MM-JJThh:mm:ssZ" - date/heure de diffusion du produit
|
||||
@SerializedName("domain_id") Domain domain, //
|
||||
@Nullable List<TextBlocItem> textBlocItems, // contenu textuel des bulletins
|
||||
Periods periods) { // périodes concernées par la Vigilance
|
||||
|
||||
public Optional<TextBlocItem> getBlocItem(Domain searched) {
|
||||
return textBlocItems != null ? textBlocItems.stream().filter(ti -> ti.validFor(searched)).findFirst()
|
||||
: Optional.empty();
|
||||
}
|
||||
|
||||
public Optional<Period> getPeriod(Term term) {
|
||||
return Optional.ofNullable(periods.get(term));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Periods extends HashMap<Term, @Nullable Period> {
|
||||
private static final long serialVersionUID = -4448877461442293135L;
|
||||
}
|
||||
|
||||
public static class Timelaps extends HashMap<Domain, @Nullable DomainId> {
|
||||
private static final long serialVersionUID = -441522278695388073L;
|
||||
}
|
||||
|
||||
public record TextBlocItem( //
|
||||
@SerializedName("domain_id") Domain domain, // code du domaine sur lequel s'applique le bloc textuel
|
||||
String blocTitle, //
|
||||
String blocId, // indique le type de bloc
|
||||
List<BlocItem> blocItems) { // rubriques du bulletin : SITUATION,QUALIFICATION, INCERTITUDE,EVOLUTION
|
||||
|
||||
private boolean validFor(Domain searched) {
|
||||
return searched.equals(domain);
|
||||
}
|
||||
}
|
||||
|
||||
public record Period( //
|
||||
Term echeance, //
|
||||
ZonedDateTime beginValidityTime, //
|
||||
ZonedDateTime endValidityTime, //
|
||||
TextItems textItems, //
|
||||
Timelaps timelaps, //
|
||||
List<PhenomenonCount> maxCountItems, //
|
||||
List<PerPhenomenonItem> perPhenomenonItems) {//
|
||||
}
|
||||
|
||||
private record TextItems( //
|
||||
String title, //
|
||||
List<String> text) {//
|
||||
}
|
||||
|
||||
public record DomainId( //
|
||||
@SerializedName("domain_id") Domain domain, //
|
||||
int maxColorId, //
|
||||
List<PhenomenonItem> phenomenonItems) { //
|
||||
}
|
||||
|
||||
public record PhenomenonItem( //
|
||||
Hazard phenomenonId, //
|
||||
Risk phenomenonMaxColorId, //
|
||||
List<TimelapsItem> timelapsItems) { //
|
||||
}
|
||||
|
||||
public record TimelapsItem( //
|
||||
ZonedDateTime beginTime, //
|
||||
ZonedDateTime endTime, //
|
||||
Risk colorId) { //
|
||||
|
||||
public boolean contains(ZonedDateTime moment) {
|
||||
return beginTime.isBefore(moment) && endTime.isAfter(moment);
|
||||
}
|
||||
}
|
||||
|
||||
private record PhenomenonCount(// )
|
||||
int colorId, //
|
||||
String colorName, //
|
||||
int count, //
|
||||
String textCount) { //
|
||||
}
|
||||
|
||||
private record PerPhenomenonItem( //
|
||||
String phenomenonId, //
|
||||
int anyColorCount, //
|
||||
List<PhenomenonCount> phenomenonCounts) { //
|
||||
}
|
||||
|
||||
public record BlocItem( //
|
||||
String id, // identifiant de la rubrique texte
|
||||
@SerializedName("type_group") BlocType type, // code du groupe de la rubrique
|
||||
List<TextItem> textItems) { // textes à associer à la carte comme les commentaires
|
||||
}
|
||||
|
||||
public record TextItem( //
|
||||
@Nullable String hazardCode, // code du phénomène
|
||||
String typeCode, // code de l'élément de suivi
|
||||
List<TermItem> termItems) {// tableau des éléments de suivi par échéance : J, J1 ou J+J1
|
||||
|
||||
public Hazard getHazard() {
|
||||
return hazardCode == null ? Hazard.ALL : Hazard.valueOf(Objects.requireNonNull(hazardCode));
|
||||
}
|
||||
}
|
||||
|
||||
public record TermItem(//
|
||||
@SerializedName("term_names") Term term, // code de l'échéance
|
||||
@SerializedName("risk_code") Risk risk, // code du risque
|
||||
ZonedDateTime startTime, // date/heure début d'échéance
|
||||
ZonedDateTime endTime, // date/heure fin d'échéance
|
||||
List<SubdivisionText> subdivisionText) {// sous_textes de même type d'éléments de suivi
|
||||
|
||||
public String getText(ZonedDateTime moment) {
|
||||
return startTime.isBefore(moment) && endTime.isAfter(moment) ? subdivisionText.stream()
|
||||
.map(SubdivisionText::getText).collect(Collectors.joining(System.lineSeparator())) : "";
|
||||
}
|
||||
}
|
||||
|
||||
private record SubdivisionText( //
|
||||
String underlineText, // texte devant être souligné dans le bulletin
|
||||
List<String> text) { // contenu du texte ligne par ligne
|
||||
|
||||
String getText() {
|
||||
return (underlineText.isEmpty() ? "" : underlineText + System.lineSeparator()) + text.stream()
|
||||
.filter(Predicate.not(String::isEmpty)).collect(Collectors.joining(System.lineSeparator()));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal.dto;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class RainForecast {
|
||||
public enum RainIntensity {
|
||||
@SerializedName("1")
|
||||
TEMPS_SEC,
|
||||
@SerializedName("2")
|
||||
FAIBLE,
|
||||
@SerializedName("3")
|
||||
MODEREE,
|
||||
@SerializedName("4")
|
||||
FORTE,
|
||||
UNKNOWN;
|
||||
}
|
||||
|
||||
public record Forecast(ZonedDateTime time, RainIntensity rainIntensity, String rainIntensityDescription) {
|
||||
}
|
||||
|
||||
public record Geometry(String type, List<Double> coordinates) {
|
||||
}
|
||||
|
||||
public class Properties {
|
||||
public int altitude;
|
||||
public String name = "";
|
||||
public String country = "";
|
||||
public String frenchDepartment = "";
|
||||
public int rainProductAvailable;
|
||||
public String timezone = "";
|
||||
public int confidence;
|
||||
public List<Forecast> forecast = List.of();
|
||||
}
|
||||
|
||||
public @Nullable ZonedDateTime updateTime;
|
||||
public String type = "";
|
||||
public @Nullable Geometry geometry;
|
||||
public @Nullable Properties properties;
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal.dto;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum Risk {
|
||||
@SerializedName("1")
|
||||
VERT("#15ed13", 0),
|
||||
@SerializedName("2")
|
||||
JAUNE("#f9ff00", 1),
|
||||
@SerializedName("3")
|
||||
ORANGE("#f7a401", 2),
|
||||
@SerializedName("4")
|
||||
ROUGE("#e71919", 3),
|
||||
UNKNOWN("#000000", -1);
|
||||
|
||||
public final String rgbColor;
|
||||
public final int riskLevel;
|
||||
|
||||
Risk(String rgbColor, int riskLevel) {
|
||||
this.rgbColor = rgbColor;
|
||||
this.riskLevel = riskLevel;
|
||||
}
|
||||
}
|
@ -10,24 +10,22 @@
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.meteoalerte.internal.json;
|
||||
package org.openhab.binding.meteofrance.internal.dto;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* The {@link Refine} is the Java class used to map the JSON
|
||||
* response to the webservice request.
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class Refine {
|
||||
@SerializedName("nom_dept")
|
||||
private String nomDept = "";
|
||||
|
||||
public String getNomDept() {
|
||||
return nomDept;
|
||||
}
|
||||
public enum Term {
|
||||
@SerializedName("J")
|
||||
TODAY,
|
||||
@SerializedName("J1")
|
||||
TOMORROW,
|
||||
@SerializedName("J+J1")
|
||||
TODAY_AND_TOMORROW,
|
||||
UNKNOWN
|
||||
}
|
@ -0,0 +1,175 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal.handler;
|
||||
|
||||
import static org.openhab.binding.meteofrance.internal.MeteoFranceBindingConstants.REQUEST_TIMEOUT_MS;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.ws.rs.HttpMethod;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.meteofrance.internal.MeteoFranceException;
|
||||
import org.openhab.binding.meteofrance.internal.config.BridgeConfiguration;
|
||||
import org.openhab.binding.meteofrance.internal.deserialization.MeteoFranceDeserializer;
|
||||
import org.openhab.binding.meteofrance.internal.dto.Domain;
|
||||
import org.openhab.binding.meteofrance.internal.dto.MeteoFrance;
|
||||
import org.openhab.binding.meteofrance.internal.dto.MeteoFrance.DomainId;
|
||||
import org.openhab.binding.meteofrance.internal.dto.MeteoFrance.Meta;
|
||||
import org.openhab.binding.meteofrance.internal.dto.MeteoFrance.Period;
|
||||
import org.openhab.binding.meteofrance.internal.dto.MeteoFrance.Product;
|
||||
import org.openhab.binding.meteofrance.internal.dto.MeteoFrance.TextBlocItem;
|
||||
import org.openhab.binding.meteofrance.internal.dto.MeteoFrance.VigilanceEnCours;
|
||||
import org.openhab.binding.meteofrance.internal.dto.RainForecast;
|
||||
import org.openhab.binding.meteofrance.internal.dto.Term;
|
||||
import org.openhab.core.cache.ExpiringCache;
|
||||
import org.openhab.core.io.net.http.HttpUtil;
|
||||
import org.openhab.core.library.types.PointType;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseBridgeHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* {@link MeteoFranceBridgeHandler} is the handler for Meteo France bridge and connects it
|
||||
* to the Meteo France API Portal
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class MeteoFranceBridgeHandler extends BaseBridgeHandler {
|
||||
private static final String PORTAIL_API_BASE_URL = "https://public-api.meteofrance.fr/public/DPVigilance/v1/%s/encours";
|
||||
private static final String TEXTE_VIGILANCE_URL = PORTAIL_API_BASE_URL.formatted("textesvigilance");
|
||||
private static final String CARTE_VIGILANCE_URL = PORTAIL_API_BASE_URL.formatted("cartevigilance");
|
||||
|
||||
private static final String RAIN_FORECAST_BASE_URL = "https://rpcache-aa.meteofrance.com/internet2018client/2.0/nowcast/rain?lat=%.4f&lon=%.4f&token=__Wj7dVSTjV9YGu1guveLyDq0g7S7TfTjaHBTPTpO0kj8__";
|
||||
|
||||
private static final long CACHE_EXPIRY = TimeUnit.MINUTES.toMillis(10);
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(MeteoFranceBridgeHandler.class);
|
||||
private final Properties header = new Properties();
|
||||
private final MeteoFranceDeserializer deserializer;
|
||||
|
||||
private final ExpiringCache<VigilanceEnCours> vigilanceText;
|
||||
private final ExpiringCache<VigilanceEnCours> vigilanceMap;
|
||||
|
||||
public MeteoFranceBridgeHandler(Bridge bridge, MeteoFranceDeserializer deserializer) {
|
||||
super(bridge);
|
||||
this.deserializer = deserializer;
|
||||
|
||||
vigilanceText = new ExpiringCache<>(CACHE_EXPIRY, () -> this.getVigilanceEnCours(TEXTE_VIGILANCE_URL));
|
||||
vigilanceMap = new ExpiringCache<>(CACHE_EXPIRY, () -> this.getVigilanceEnCours(CARTE_VIGILANCE_URL));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
logger.debug("Initializing Meteo-France API bridge handler.");
|
||||
BridgeConfiguration config = getConfigAs(BridgeConfiguration.class);
|
||||
if (config.apikey.isEmpty()) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||
"@text/offline.config-error-unknown-apikey");
|
||||
return;
|
||||
}
|
||||
header.put("apikey", config.apikey);
|
||||
header.put("accept", "*/*");
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
scheduler.execute(() -> vigilanceText.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
header.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
// The bridge does not handle commands
|
||||
}
|
||||
|
||||
private @Nullable VigilanceEnCours getVigilanceEnCours(String url) {
|
||||
try {
|
||||
String answer = HttpUtil.executeUrl(HttpMethod.GET, url, header, null, null, REQUEST_TIMEOUT_MS);
|
||||
logger.trace(answer);
|
||||
|
||||
VigilanceEnCours vigilance = deserializer.deserialize(MeteoFrance.VigilanceEnCours.class, answer);
|
||||
if (vigilance.code() != 0) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, vigilance.message());
|
||||
} else {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
return vigilance;
|
||||
}
|
||||
} catch (MeteoFranceException e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Exception deserializing API answer: %s".formatted(e.getMessage()));
|
||||
} catch (IOException e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public @Nullable TextBlocItem requestTextData(Domain domain) {
|
||||
VigilanceEnCours local = vigilanceText.getValue();
|
||||
if (local != null) {
|
||||
Product product = local.product();
|
||||
if (product != null) {
|
||||
return product.getBlocItem(domain).get();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public @Nullable DomainId requestMapData(Domain domain, Term term) {
|
||||
Period period = requestPeriod(term);
|
||||
return period != null ? period.timelaps().get(domain) : null;
|
||||
}
|
||||
|
||||
public @Nullable Period requestPeriod(Term term) {
|
||||
VigilanceEnCours local = vigilanceMap.getValue();
|
||||
if (local != null) {
|
||||
Product product = local.product();
|
||||
if (product != null) {
|
||||
return product.getPeriod(term).get();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Optional<Meta> getMeta() {
|
||||
VigilanceEnCours local = vigilanceText.getValue();
|
||||
return Optional.ofNullable(local != null ? local.meta() : null);
|
||||
}
|
||||
|
||||
public @Nullable RainForecast getRainForecast(PointType location) {
|
||||
String url = RAIN_FORECAST_BASE_URL.formatted(location.getLatitude().doubleValue(),
|
||||
location.getLongitude().doubleValue());
|
||||
try {
|
||||
String answer = HttpUtil.executeUrl(HttpMethod.GET, url, REQUEST_TIMEOUT_MS);
|
||||
return deserializer.deserialize(RainForecast.class, answer);
|
||||
} catch (MeteoFranceException e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Exception deserializing API answer: %s".formatted(e.getMessage()));
|
||||
} catch (IOException e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal.handler;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
|
||||
/**
|
||||
* {@link MeteoFranceChildHandler} is a common interface for Things having a
|
||||
* {@link MeteoFranceBridgeHandler} Bridge
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface MeteoFranceChildHandler {
|
||||
default Optional<MeteoFranceBridgeHandler> getBridgeHandler() {
|
||||
Bridge bridge = getBridge();
|
||||
if (bridge != null) {
|
||||
if (bridge.getHandler() instanceof MeteoFranceBridgeHandler maHandler) {
|
||||
return Optional.of(maHandler);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
Bridge getBridge();
|
||||
}
|
@ -0,0 +1,167 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal.handler;
|
||||
|
||||
import static org.openhab.binding.meteofrance.internal.MeteoFranceBindingConstants.*;
|
||||
import static org.openhab.core.types.TimeSeries.Policy.REPLACE;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
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.meteofrance.internal.config.ForecastConfiguration;
|
||||
import org.openhab.binding.meteofrance.internal.dto.RainForecast;
|
||||
import org.openhab.binding.meteofrance.internal.dto.RainForecast.Forecast;
|
||||
import org.openhab.binding.meteofrance.internal.dto.RainForecast.Properties;
|
||||
import org.openhab.binding.meteofrance.internal.dto.RainForecast.RainIntensity;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.PointType;
|
||||
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.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.TimeSeries;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link RainForecastHandler} is responsible for updating channels
|
||||
* and querying the API
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class RainForecastHandler extends BaseThingHandler implements MeteoFranceChildHandler {
|
||||
private final Logger logger = LoggerFactory.getLogger(RainForecastHandler.class);
|
||||
private final ChannelUID intensityChannelUID;
|
||||
private final ZoneId systemZoneId;
|
||||
|
||||
private Optional<ScheduledFuture<?>> refreshJob = Optional.empty();
|
||||
private Optional<PointType> location = Optional.empty();
|
||||
|
||||
public RainForecastHandler(Thing thing, ZoneId zoneId) {
|
||||
super(thing);
|
||||
this.intensityChannelUID = new ChannelUID(getThing().getUID(), INTENSITY);
|
||||
this.systemZoneId = zoneId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Bridge getBridge() {
|
||||
return super.getBridge();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
logger.debug("Initializing Rain Forecast handler.");
|
||||
disposeJob();
|
||||
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
|
||||
ForecastConfiguration config = getConfigAs(ForecastConfiguration.class);
|
||||
|
||||
try {
|
||||
this.location = Optional.of(new PointType(config.location));
|
||||
} catch (IllegalArgumentException e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Incorrect 'location' value.");
|
||||
return;
|
||||
}
|
||||
|
||||
this.refreshJob = Optional.of(scheduler.schedule(this::updateAndPublish, 2, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
private void disposeJob() {
|
||||
refreshJob.ifPresent(job -> job.cancel(true));
|
||||
refreshJob = Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
logger.debug("Disposing the Rain Forecast handler.");
|
||||
disposeJob();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (command instanceof RefreshType) {
|
||||
updateAndPublish();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAndPublish() {
|
||||
getBridgeHandler().ifPresentOrElse(handler -> {
|
||||
location.ifPresent(loc -> {
|
||||
RainForecast forecast = handler.getRainForecast(loc);
|
||||
if (forecast != null) {
|
||||
setProperties(forecast.properties);
|
||||
updateDate(UPDATE_TIME, forecast.updateTime);
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
}
|
||||
});
|
||||
}, () -> logger.warn("No viable bridge"));
|
||||
}
|
||||
|
||||
private void setProperties(@Nullable Properties forecastProps) {
|
||||
if (forecastProps == null) {
|
||||
return;
|
||||
}
|
||||
Map<String, String> properties = editProperties();
|
||||
properties.put("altitude", "%d m".formatted(forecastProps.altitude));
|
||||
properties.put("name", forecastProps.name);
|
||||
properties.put("country", forecastProps.country);
|
||||
properties.put("department", forecastProps.frenchDepartment);
|
||||
properties.put("timezone", forecastProps.timezone);
|
||||
properties.put("comfidence", "%d".formatted(forecastProps.confidence));
|
||||
this.updateProperties(properties);
|
||||
|
||||
setForecast(forecastProps.forecast);
|
||||
}
|
||||
|
||||
private void setForecast(List<Forecast> forecast) {
|
||||
TimeSeries timeSeries = new TimeSeries(REPLACE);
|
||||
|
||||
forecast.forEach(prevision -> {
|
||||
State state = prevision.rainIntensity() != RainIntensity.UNKNOWN
|
||||
? new DecimalType(prevision.rainIntensity().ordinal())
|
||||
: UnDefType.UNDEF;
|
||||
timeSeries.add(prevision.time().toInstant(), state);
|
||||
});
|
||||
sendTimeSeries(intensityChannelUID, timeSeries);
|
||||
|
||||
Forecast current = forecast.get(0);
|
||||
long until = ZonedDateTime.now().until(current.time(), ChronoUnit.SECONDS);
|
||||
logger.debug("Refresh rain intensity forecast in : {}s", until);
|
||||
refreshJob = Optional.of(scheduler.schedule(this::updateAndPublish, until, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
private void updateDate(String channelId, @Nullable ZonedDateTime zonedDateTime) {
|
||||
if (isLinked(channelId)) {
|
||||
updateState(channelId,
|
||||
zonedDateTime != null ? new DateTimeType(zonedDateTime.withZoneSameInstant(systemZoneId))
|
||||
: UnDefType.NULL);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,189 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2024 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.meteofrance.internal.handler;
|
||||
|
||||
import static org.openhab.binding.meteofrance.internal.MeteoFranceBindingConstants.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.meteofrance.internal.MeteoFranceIconProvider;
|
||||
import org.openhab.binding.meteofrance.internal.config.DepartmentConfiguration;
|
||||
import org.openhab.binding.meteofrance.internal.dto.BlocType;
|
||||
import org.openhab.binding.meteofrance.internal.dto.Domain;
|
||||
import org.openhab.binding.meteofrance.internal.dto.Hazard;
|
||||
import org.openhab.binding.meteofrance.internal.dto.MeteoFrance.DomainId;
|
||||
import org.openhab.binding.meteofrance.internal.dto.MeteoFrance.Period;
|
||||
import org.openhab.binding.meteofrance.internal.dto.MeteoFrance.TextBlocItem;
|
||||
import org.openhab.binding.meteofrance.internal.dto.MeteoFrance.TimelapsItem;
|
||||
import org.openhab.binding.meteofrance.internal.dto.Risk;
|
||||
import org.openhab.binding.meteofrance.internal.dto.Term;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.RawType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
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.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link VigilanceHandler} is responsible for updating channels
|
||||
* and querying the API
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class VigilanceHandler extends BaseThingHandler implements MeteoFranceChildHandler {
|
||||
private final Logger logger = LoggerFactory.getLogger(VigilanceHandler.class);
|
||||
private final MeteoFranceIconProvider iconProvider;
|
||||
private final ZoneId systemZoneId;
|
||||
|
||||
private Optional<ScheduledFuture<?>> refreshJob = Optional.empty();
|
||||
|
||||
private @NonNullByDefault({}) Domain domain;
|
||||
|
||||
public VigilanceHandler(Thing thing, ZoneId zoneId, MeteoFranceIconProvider iconProvider) {
|
||||
super(thing);
|
||||
this.iconProvider = iconProvider;
|
||||
this.systemZoneId = zoneId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Bridge getBridge() {
|
||||
return super.getBridge();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
logger.debug("Initializing Vigilance Météo handler.");
|
||||
disposeJob();
|
||||
|
||||
DepartmentConfiguration config = getConfigAs(DepartmentConfiguration.class);
|
||||
|
||||
domain = Domain.getByApiId(config.department);
|
||||
if (Domain.UNKNOWN.equals(domain)) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
|
||||
"Wrong department: %s".formatted((config.department)));
|
||||
return;
|
||||
}
|
||||
logger.debug("config department= {}", config.department);
|
||||
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
refreshJob = Optional
|
||||
.of(scheduler.scheduleWithFixedDelay(this::updateAndPublish, 5, config.refresh * 60, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
private void disposeJob() {
|
||||
refreshJob.ifPresent(job -> job.cancel(true));
|
||||
refreshJob = Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
logger.debug("Disposing the Vigilance Météo handler.");
|
||||
disposeJob();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (command instanceof RefreshType) {
|
||||
updateAndPublish();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAndPublish() {
|
||||
getBridgeHandler().ifPresentOrElse(handler -> {
|
||||
Period period = handler.requestPeriod(Term.TODAY);
|
||||
if (period != null) {
|
||||
updateDate(OBSERVATION_TIME, period.beginValidityTime());
|
||||
updateDate(END_TIME, period.endValidityTime());
|
||||
}
|
||||
DomainId domainId = handler.requestMapData(domain, Term.TODAY);
|
||||
ZonedDateTime now = ZonedDateTime.now().withZoneSameInstant(systemZoneId);
|
||||
if (domainId != null) {
|
||||
Map<Hazard, Risk> channels = new HashMap<>(Hazard.values().length);
|
||||
Hazard.AS_SET.stream().filter(Hazard::isChannel).forEach(hazard -> channels.put(hazard, Risk.VERT));
|
||||
|
||||
domainId.phenomenonItems().forEach(phenomenon -> {
|
||||
Risk risk = phenomenon.phenomenonMaxColorId();
|
||||
for (TimelapsItem item : phenomenon.timelapsItems()) {
|
||||
if (item.contains(now)) {
|
||||
risk = item.colorId();
|
||||
}
|
||||
}
|
||||
channels.put(phenomenon.phenomenonId(), risk);
|
||||
});
|
||||
|
||||
channels.forEach((k, v) -> updateAlert(k.channelName, v));
|
||||
|
||||
TextBlocItem bloc = handler.requestTextData(domain);
|
||||
if (bloc != null) {
|
||||
String comment = bloc.blocItems().stream().filter(bi -> bi.type().equals(BlocType.SITUATION))
|
||||
.flatMap(bi -> bi.textItems().stream()).flatMap(ti -> ti.termItems().stream())
|
||||
.map(term -> term.getText(now)).collect(Collectors.joining("."));
|
||||
updateState(COMMENT, comment.isEmpty() ? UnDefType.NULL : StringType.valueOf(comment));
|
||||
}
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.NONE, "No data available for the department");
|
||||
}
|
||||
}, () -> logger.warn("No viable bridge"));
|
||||
}
|
||||
|
||||
private void updateAlert(String channelId, Risk value) {
|
||||
State state = value != Risk.UNKNOWN ? new DecimalType(value.riskLevel) : UnDefType.NULL;
|
||||
if (isLinked(channelId)) {
|
||||
updateState(channelId, state);
|
||||
}
|
||||
|
||||
String channelIcon = channelId + "-icon";
|
||||
if (isLinked(channelIcon)) {
|
||||
InputStream icon = iconProvider.getIcon(channelId, state.toString());
|
||||
if (icon != null) {
|
||||
try {
|
||||
State result = new RawType(icon.readAllBytes(), "image/svg+xml");
|
||||
updateState(channelIcon, result);
|
||||
} catch (IOException e) {
|
||||
logger.warn("Error getting icon for channel {} and value {}: {}", channelId, value, e.getMessage());
|
||||
}
|
||||
} else {
|
||||
logger.warn("Null icon returned for channel {} and state {}", channelIcon, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDate(String channelId, ZonedDateTime zonedDateTime) {
|
||||
if (isLinked(channelId)) {
|
||||
updateState(channelId, new DateTimeType(zonedDateTime.withZoneSameInstant(systemZoneId)));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<addon:addon id="meteoalerte" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<addon:addon id="meteofrance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:addon="https://openhab.org/schemas/addon/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/addon/v1.0.0 https://openhab.org/schemas/addon-1.0.0.xsd">
|
||||
|
||||
<type>binding</type>
|
||||
<name>Meteo Alerte Binding</name>
|
||||
<description>Retrieves Meteo Alert levels in France</description>
|
||||
<name>Météo France Binding</name>
|
||||
<description>Retrieves various weather information from Météo France APIs</description>
|
||||
<connection>cloud</connection>
|
||||
<countries>fr</countries>
|
||||
|
@ -0,0 +1,211 @@
|
||||
# add-on
|
||||
|
||||
addon.meteofrance.name = Météo France Binding
|
||||
addon.meteofrance.description = Retrieves various weather information from Météo France APIs
|
||||
|
||||
# thing types
|
||||
|
||||
thing-type.meteofrance.api.label = Météo-France API Portal
|
||||
thing-type.meteofrance.api.description = Bridge to the Météo-France API Portal. In order to receive the data, you must register an account on https://portail-api.meteofrance.fr/devportal/apis and get your API token.
|
||||
thing-type.meteofrance.rain-forecast.label = Precipitation Forecast
|
||||
thing-type.meteofrance.rain-forecast.description = Provides precipitation forecast for the next hour
|
||||
thing-type.meteofrance.vigilance.label = Department Awareness
|
||||
thing-type.meteofrance.vigilance.description = Provides weather alert levels for a department.
|
||||
thing-type.meteofrance.vigilance.channel.avalanches-icon.label = Avalanche Icon
|
||||
thing-type.meteofrance.vigilance.channel.canicule-icon.label = Heat Wave Icon
|
||||
thing-type.meteofrance.vigilance.channel.end-time.label = End of Validity
|
||||
thing-type.meteofrance.vigilance.channel.grand-froid-icon.label = Extreme Cold Icon
|
||||
thing-type.meteofrance.vigilance.channel.inondation-icon.label = Flood Icon
|
||||
thing-type.meteofrance.vigilance.channel.neige-icon.label = Snow Icon
|
||||
thing-type.meteofrance.vigilance.channel.observation-time.label = Start of Validity
|
||||
thing-type.meteofrance.vigilance.channel.orage-icon.label = Storm Icon
|
||||
thing-type.meteofrance.vigilance.channel.pluie-inondation-icon.label = Rain Flood Icon
|
||||
thing-type.meteofrance.vigilance.channel.vague-submersion-icon.label = Wave Submersion Icon
|
||||
thing-type.meteofrance.vigilance.channel.vent-icon.label = Wind Icon
|
||||
|
||||
# thing types config
|
||||
|
||||
thing-type.config.meteofrance.api.apikey.label = API Key
|
||||
thing-type.config.meteofrance.api.apikey.description = Data-platform token to access the service
|
||||
thing-type.config.meteofrance.rain-forecast.location.label = Location
|
||||
thing-type.config.meteofrance.rain-forecast.location.description = Your geo coordinates separated with comma (e.g. "37.8,-122.4,177").
|
||||
thing-type.config.meteofrance.vigilance.department.label = Department
|
||||
thing-type.config.meteofrance.vigilance.department.description = Name of the department
|
||||
thing-type.config.meteofrance.vigilance.department.option.01 = Ain
|
||||
thing-type.config.meteofrance.vigilance.department.option.02 = Aisne
|
||||
thing-type.config.meteofrance.vigilance.department.option.03 = Allier
|
||||
thing-type.config.meteofrance.vigilance.department.option.04 = Alpes de Haute Provence
|
||||
thing-type.config.meteofrance.vigilance.department.option.06 = Alpes Maritimes
|
||||
thing-type.config.meteofrance.vigilance.department.option.07 = Ardèche
|
||||
thing-type.config.meteofrance.vigilance.department.option.08 = Ardennes
|
||||
thing-type.config.meteofrance.vigilance.department.option.09 = Ariège
|
||||
thing-type.config.meteofrance.vigilance.department.option.10 = Aube
|
||||
thing-type.config.meteofrance.vigilance.department.option.11 = Aude
|
||||
thing-type.config.meteofrance.vigilance.department.option.12 = Aveyron
|
||||
thing-type.config.meteofrance.vigilance.department.option.67 = Bas-Rhin
|
||||
thing-type.config.meteofrance.vigilance.department.option.13 = Bouches du Rhône
|
||||
thing-type.config.meteofrance.vigilance.department.option.14 = Calvados
|
||||
thing-type.config.meteofrance.vigilance.department.option.15 = Cantal
|
||||
thing-type.config.meteofrance.vigilance.department.option.16 = Charente
|
||||
thing-type.config.meteofrance.vigilance.department.option.17 = Charente Maritime
|
||||
thing-type.config.meteofrance.vigilance.department.option.18 = Cher
|
||||
thing-type.config.meteofrance.vigilance.department.option.19 = Corrèze
|
||||
thing-type.config.meteofrance.vigilance.department.option.2A = Corse du Sud
|
||||
thing-type.config.meteofrance.vigilance.department.option.21 = Côte D'Or
|
||||
thing-type.config.meteofrance.vigilance.department.option.22 = Côtes D'Armor
|
||||
thing-type.config.meteofrance.vigilance.department.option.23 = Creuse
|
||||
thing-type.config.meteofrance.vigilance.department.option.79 = Deux Sèvres
|
||||
thing-type.config.meteofrance.vigilance.department.option.24 = Dordogne
|
||||
thing-type.config.meteofrance.vigilance.department.option.25 = Doubs
|
||||
thing-type.config.meteofrance.vigilance.department.option.26 = Drôme
|
||||
thing-type.config.meteofrance.vigilance.department.option.91 = Essonne
|
||||
thing-type.config.meteofrance.vigilance.department.option.27 = Eure
|
||||
thing-type.config.meteofrance.vigilance.department.option.28 = Eure et Loir
|
||||
thing-type.config.meteofrance.vigilance.department.option.29 = Finistère
|
||||
thing-type.config.meteofrance.vigilance.department.option.30 = Gard
|
||||
thing-type.config.meteofrance.vigilance.department.option.32 = Gers
|
||||
thing-type.config.meteofrance.vigilance.department.option.33 = Gironde
|
||||
thing-type.config.meteofrance.vigilance.department.option.68 = Haut-Rhin
|
||||
thing-type.config.meteofrance.vigilance.department.option.2B = Haute Corse
|
||||
thing-type.config.meteofrance.vigilance.department.option.31 = Haute Garonne
|
||||
thing-type.config.meteofrance.vigilance.department.option.43 = Haute Loire
|
||||
thing-type.config.meteofrance.vigilance.department.option.52 = Haute Marne
|
||||
thing-type.config.meteofrance.vigilance.department.option.70 = Haute Saône
|
||||
thing-type.config.meteofrance.vigilance.department.option.74 = Haute Savoie
|
||||
thing-type.config.meteofrance.vigilance.department.option.87 = Haute Vienne
|
||||
thing-type.config.meteofrance.vigilance.department.option.05 = Hautes Alpes
|
||||
thing-type.config.meteofrance.vigilance.department.option.65 = Hautes Pyrénées
|
||||
thing-type.config.meteofrance.vigilance.department.option.92 = Hauts de Seine
|
||||
thing-type.config.meteofrance.vigilance.department.option.34 = Hérault
|
||||
thing-type.config.meteofrance.vigilance.department.option.35 = Ille et Vilaine
|
||||
thing-type.config.meteofrance.vigilance.department.option.36 = Indre
|
||||
thing-type.config.meteofrance.vigilance.department.option.37 = Indre et Loire
|
||||
thing-type.config.meteofrance.vigilance.department.option.38 = Isère
|
||||
thing-type.config.meteofrance.vigilance.department.option.39 = Jura
|
||||
thing-type.config.meteofrance.vigilance.department.option.40 = Landes
|
||||
thing-type.config.meteofrance.vigilance.department.option.41 = Loir et Cher
|
||||
thing-type.config.meteofrance.vigilance.department.option.42 = Loire
|
||||
thing-type.config.meteofrance.vigilance.department.option.44 = Loire Atlantique
|
||||
thing-type.config.meteofrance.vigilance.department.option.45 = Loiret
|
||||
thing-type.config.meteofrance.vigilance.department.option.46 = Lot
|
||||
thing-type.config.meteofrance.vigilance.department.option.47 = Lot et Garonne
|
||||
thing-type.config.meteofrance.vigilance.department.option.48 = Lozère
|
||||
thing-type.config.meteofrance.vigilance.department.option.49 = Maine et Loire
|
||||
thing-type.config.meteofrance.vigilance.department.option.50 = Manche
|
||||
thing-type.config.meteofrance.vigilance.department.option.51 = Marne
|
||||
thing-type.config.meteofrance.vigilance.department.option.53 = Mayenne
|
||||
thing-type.config.meteofrance.vigilance.department.option.54 = Meurthe et Moselle
|
||||
thing-type.config.meteofrance.vigilance.department.option.55 = Meuse
|
||||
thing-type.config.meteofrance.vigilance.department.option.56 = Morbihan
|
||||
thing-type.config.meteofrance.vigilance.department.option.57 = Moselle
|
||||
thing-type.config.meteofrance.vigilance.department.option.58 = Nièvre
|
||||
thing-type.config.meteofrance.vigilance.department.option.59 = Nord
|
||||
thing-type.config.meteofrance.vigilance.department.option.60 = Oise
|
||||
thing-type.config.meteofrance.vigilance.department.option.61 = Orne
|
||||
thing-type.config.meteofrance.vigilance.department.option.75 = Paris
|
||||
thing-type.config.meteofrance.vigilance.department.option.62 = Pas de Calais
|
||||
thing-type.config.meteofrance.vigilance.department.option.63 = Puy de Dôme
|
||||
thing-type.config.meteofrance.vigilance.department.option.64 = Pyrénées Atlantiques
|
||||
thing-type.config.meteofrance.vigilance.department.option.66 = Pyrénées Orientales
|
||||
thing-type.config.meteofrance.vigilance.department.option.69 = Rhône
|
||||
thing-type.config.meteofrance.vigilance.department.option.71 = Saône et Loire
|
||||
thing-type.config.meteofrance.vigilance.department.option.72 = Sarthe
|
||||
thing-type.config.meteofrance.vigilance.department.option.73 = Savoie
|
||||
thing-type.config.meteofrance.vigilance.department.option.77 = Seine et Marne
|
||||
thing-type.config.meteofrance.vigilance.department.option.76 = Seine Maritime
|
||||
thing-type.config.meteofrance.vigilance.department.option.93 = Seine Saint Denis
|
||||
thing-type.config.meteofrance.vigilance.department.option.80 = Somme
|
||||
thing-type.config.meteofrance.vigilance.department.option.81 = Tarn
|
||||
thing-type.config.meteofrance.vigilance.department.option.82 = Tarn et Garonne
|
||||
thing-type.config.meteofrance.vigilance.department.option.90 = Territoire de Belfort
|
||||
thing-type.config.meteofrance.vigilance.department.option.95 = Val D'Oise
|
||||
thing-type.config.meteofrance.vigilance.department.option.94 = Val de Marne
|
||||
thing-type.config.meteofrance.vigilance.department.option.83 = Var
|
||||
thing-type.config.meteofrance.vigilance.department.option.84 = Vaucluse
|
||||
thing-type.config.meteofrance.vigilance.department.option.85 = Vendée
|
||||
thing-type.config.meteofrance.vigilance.department.option.86 = Vienne
|
||||
thing-type.config.meteofrance.vigilance.department.option.88 = Vosges
|
||||
thing-type.config.meteofrance.vigilance.department.option.89 = Yonne
|
||||
thing-type.config.meteofrance.vigilance.department.option.78 = Yvelines
|
||||
thing-type.config.meteofrance.vigilance.refresh.label = Refresh Rate
|
||||
thing-type.config.meteofrance.vigilance.refresh.description = Data refresh period in minutes.
|
||||
|
||||
# channel types
|
||||
|
||||
channel-type.meteofrance.avalanches.label = Avalanches
|
||||
channel-type.meteofrance.avalanches.description = Avalanche alert level
|
||||
channel-type.meteofrance.avalanches.state.option.0 = No special vigilance
|
||||
channel-type.meteofrance.avalanches.state.option.1 = Be attentive
|
||||
channel-type.meteofrance.avalanches.state.option.2 = Be very vigilant
|
||||
channel-type.meteofrance.avalanches.state.option.3 = Absolute vigilance
|
||||
channel-type.meteofrance.canicule.label = Heat Wave
|
||||
channel-type.meteofrance.canicule.description = High temperature alert level
|
||||
channel-type.meteofrance.canicule.state.option.0 = No special vigilance
|
||||
channel-type.meteofrance.canicule.state.option.1 = Be attentive
|
||||
channel-type.meteofrance.canicule.state.option.2 = Be very vigilant
|
||||
channel-type.meteofrance.canicule.state.option.3 = Absolute vigilance
|
||||
channel-type.meteofrance.comment.label = Comment
|
||||
channel-type.meteofrance.condition-icon.label = Icon
|
||||
channel-type.meteofrance.condition-icon.description = Pictogram associated with the alert level.
|
||||
channel-type.meteofrance.grand-froid.label = Extreme Cold
|
||||
channel-type.meteofrance.grand-froid.description = Negative temperature alert level
|
||||
channel-type.meteofrance.grand-froid.state.option.0 = No special vigilance
|
||||
channel-type.meteofrance.grand-froid.state.option.1 = Be attentive
|
||||
channel-type.meteofrance.grand-froid.state.option.2 = Be very vigilant
|
||||
channel-type.meteofrance.grand-froid.state.option.3 = Absolute vigilance
|
||||
channel-type.meteofrance.inondation.label = Flood
|
||||
channel-type.meteofrance.inondation.description = Flood alert level
|
||||
channel-type.meteofrance.inondation.state.option.0 = No special vigilance
|
||||
channel-type.meteofrance.inondation.state.option.1 = Be attentive
|
||||
channel-type.meteofrance.inondation.state.option.2 = Be very vigilant
|
||||
channel-type.meteofrance.inondation.state.option.3 = Absolute vigilance
|
||||
channel-type.meteofrance.neige.label = Snow
|
||||
channel-type.meteofrance.neige.description = Snow event alert level
|
||||
channel-type.meteofrance.neige.state.option.0 = No special vigilance
|
||||
channel-type.meteofrance.neige.state.option.1 = Be attentive
|
||||
channel-type.meteofrance.neige.state.option.2 = Be very vigilant
|
||||
channel-type.meteofrance.neige.state.option.3 = Absolute vigilance
|
||||
channel-type.meteofrance.orage.label = Storm
|
||||
channel-type.meteofrance.orage.description = Storm alert level
|
||||
channel-type.meteofrance.orage.state.option.0 = No special vigilance
|
||||
channel-type.meteofrance.orage.state.option.1 = Be attentive
|
||||
channel-type.meteofrance.orage.state.option.2 = Be very vigilant
|
||||
channel-type.meteofrance.orage.state.option.3 = Absolute vigilance
|
||||
channel-type.meteofrance.pluie-inondation.label = Rain Flood
|
||||
channel-type.meteofrance.pluie-inondation.description = Flood caused by rainfall alert level
|
||||
channel-type.meteofrance.pluie-inondation.state.option.0 = No special vigilance
|
||||
channel-type.meteofrance.pluie-inondation.state.option.1 = Be attentive
|
||||
channel-type.meteofrance.pluie-inondation.state.option.2 = Be very vigilant
|
||||
channel-type.meteofrance.pluie-inondation.state.option.3 = Absolute vigilance
|
||||
channel-type.meteofrance.rain-intensity.label = Intensity
|
||||
channel-type.meteofrance.rain-intensity.description = Rain intensity level
|
||||
channel-type.meteofrance.rain-intensity.state.option.0 = Dry Weather
|
||||
channel-type.meteofrance.rain-intensity.state.option.1 = Light Rain
|
||||
channel-type.meteofrance.rain-intensity.state.option.2 = Moderate Rain
|
||||
channel-type.meteofrance.rain-intensity.state.option.3 = Heavy Rain
|
||||
channel-type.meteofrance.timestamp.label = Observation Timestamp
|
||||
channel-type.meteofrance.vague-submersion.label = Wave Submersion
|
||||
channel-type.meteofrance.vague-submersion.description = Submersion wave alert level
|
||||
channel-type.meteofrance.vague-submersion.state.option.0 = No special vigilance
|
||||
channel-type.meteofrance.vague-submersion.state.option.1 = Be attentive
|
||||
channel-type.meteofrance.vague-submersion.state.option.2 = Be very vigilant
|
||||
channel-type.meteofrance.vague-submersion.state.option.3 = Absolute vigilance
|
||||
channel-type.meteofrance.vent.label = Wind
|
||||
channel-type.meteofrance.vent.description = Wind event alert level
|
||||
channel-type.meteofrance.vent.state.option.0 = No special vigilance
|
||||
channel-type.meteofrance.vent.state.option.1 = Be attentive
|
||||
channel-type.meteofrance.vent.state.option.2 = Be very vigilant
|
||||
channel-type.meteofrance.vent.state.option.3 = Absolute vigilance
|
||||
|
||||
# iconprovider
|
||||
|
||||
iconset.label = Météo France Icons
|
||||
iconset.description = Icons illustrating weather alerts provided by Météo France
|
||||
|
||||
# discovery result
|
||||
|
||||
discovery.meteofrance.rain-forecast.local.label = Prévisions de Précipitations
|
||||
|
||||
# thing status descriptions
|
||||
|
||||
offline.config-error-unknown-apikey = Parameter 'apikey' must be configured.
|
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="meteofrance"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<bridge-type id="api">
|
||||
<label>Météo-France API Portal</label>
|
||||
<description>
|
||||
Bridge to the Météo-France API Portal. In order to receive the data, you must register an account on
|
||||
https://portail-api.meteofrance.fr/devportal/apis and get your API token.
|
||||
</description>
|
||||
<config-description>
|
||||
<parameter name="apikey" type="text" required="true">
|
||||
<label>API Key</label>
|
||||
<description>Data-platform token to access the service</description>
|
||||
<context>password</context>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</bridge-type>
|
||||
|
||||
</thing:thing-descriptions>
|
@ -0,0 +1,178 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="meteofrance"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<channel-type id="rain-intensity">
|
||||
<item-type>Number</item-type>
|
||||
<label>Intensity</label>
|
||||
<description>Rain intensity level</description>
|
||||
<category>oh:meteofrance:intensity</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">Dry Weather</option>
|
||||
<option value="1">Light Rain</option>
|
||||
<option value="2">Moderate Rain</option>
|
||||
<option value="3">Heavy Rain</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="vent">
|
||||
<item-type>Number</item-type>
|
||||
<label>Wind</label>
|
||||
<description>Wind event alert level</description>
|
||||
<category>oh:meteofrance:vent</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">No special vigilance</option>
|
||||
<option value="1">Be attentive</option>
|
||||
<option value="2">Be very vigilant</option>
|
||||
<option value="3">Absolute vigilance</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="orage">
|
||||
<item-type>Number</item-type>
|
||||
<label>Storm</label>
|
||||
<description>Storm alert level</description>
|
||||
<category>oh:meteofrance:orage</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">No special vigilance</option>
|
||||
<option value="1">Be attentive</option>
|
||||
<option value="2">Be very vigilant</option>
|
||||
<option value="3">Absolute vigilance</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="inondation">
|
||||
<item-type>Number</item-type>
|
||||
<label>Flood</label>
|
||||
<description>Flood alert level</description>
|
||||
<category>oh:meteofrance:inondation</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">No special vigilance</option>
|
||||
<option value="1">Be attentive</option>
|
||||
<option value="2">Be very vigilant</option>
|
||||
<option value="3">Absolute vigilance</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="neige">
|
||||
<item-type>Number</item-type>
|
||||
<label>Snow</label>
|
||||
<description>Snow event alert level</description>
|
||||
<category>oh:meteofrance:neige</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">No special vigilance</option>
|
||||
<option value="1">Be attentive</option>
|
||||
<option value="2">Be very vigilant</option>
|
||||
<option value="3">Absolute vigilance</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="canicule">
|
||||
<item-type>Number</item-type>
|
||||
<label>Heat Wave</label>
|
||||
<description>High temperature alert level</description>
|
||||
<category>oh:meteofrance:canicule</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">No special vigilance</option>
|
||||
<option value="1">Be attentive</option>
|
||||
<option value="2">Be very vigilant</option>
|
||||
<option value="3">Absolute vigilance</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="grand-froid">
|
||||
<item-type>Number</item-type>
|
||||
<label>Extreme Cold</label>
|
||||
<description>Negative temperature alert level</description>
|
||||
<category>oh:meteofrance:grand-froid</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">No special vigilance</option>
|
||||
<option value="1">Be attentive</option>
|
||||
<option value="2">Be very vigilant</option>
|
||||
<option value="3">Absolute vigilance</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="avalanches">
|
||||
<item-type>Number</item-type>
|
||||
<label>Avalanches</label>
|
||||
<description>Avalanche alert level</description>
|
||||
<category>oh:meteofrance:avalanches</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">No special vigilance</option>
|
||||
<option value="1">Be attentive</option>
|
||||
<option value="2">Be very vigilant</option>
|
||||
<option value="3">Absolute vigilance</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="vague-submersion">
|
||||
<item-type>Number</item-type>
|
||||
<label>Wave Submersion</label>
|
||||
<description>Submersion wave alert level</description>
|
||||
<category>oh:meteofrance:vague-submersion</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">No special vigilance</option>
|
||||
<option value="1">Be attentive</option>
|
||||
<option value="2">Be very vigilant</option>
|
||||
<option value="3">Absolute vigilance</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="pluie-inondation">
|
||||
<item-type>Number</item-type>
|
||||
<label>Rain Flood</label>
|
||||
<description>Flood caused by rainfall alert level</description>
|
||||
<category>oh:meteofrance:pluie-inondation</category>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">No special vigilance</option>
|
||||
<option value="1">Be attentive</option>
|
||||
<option value="2">Be very vigilant</option>
|
||||
<option value="3">Absolute vigilance</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="comment">
|
||||
<item-type>String</item-type>
|
||||
<label>Comment</label>
|
||||
<category>text</category>
|
||||
<state readOnly="true" pattern="%s"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="timestamp" advanced="true">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>Observation Timestamp</label>
|
||||
<category>time</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="condition-icon">
|
||||
<item-type>Image</item-type>
|
||||
<label>Icon</label>
|
||||
<description>Pictogram associated with the alert level.</description>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
</thing:thing-descriptions>
|
@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="meteofrance"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="rain-forecast">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="api"/>
|
||||
</supported-bridge-type-refs>
|
||||
<label>Precipitation Forecast</label>
|
||||
<description>Provides precipitation forecast for the next hour</description>
|
||||
|
||||
<channels>
|
||||
<channel id="update-time" typeId="timestamp"/>
|
||||
<channel id="intensity" typeId="rain-intensity"/>
|
||||
</channels>
|
||||
|
||||
<representation-property>location</representation-property>
|
||||
|
||||
<config-description>
|
||||
<parameter name="location" type="text" required="true">
|
||||
<label>Location</label>
|
||||
<context>location</context>
|
||||
<description>Your geo coordinates separated with comma (e.g. "37.8,-122.4,177").</description>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
@ -0,0 +1,175 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="meteofrance"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="vigilance">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="api"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Department Awareness</label>
|
||||
<description>Provides weather alert levels for a department.</description>
|
||||
|
||||
<channels>
|
||||
<channel id="vague-submersion" typeId="vague-submersion"/>
|
||||
<channel id="vent" typeId="vent"/>
|
||||
<channel id="pluie-inondation" typeId="pluie-inondation"/>
|
||||
<channel id="orage" typeId="orage"/>
|
||||
<channel id="inondation" typeId="inondation"/>
|
||||
<channel id="neige" typeId="neige"/>
|
||||
<channel id="canicule" typeId="canicule"/>
|
||||
<channel id="grand-froid" typeId="grand-froid"/>
|
||||
<channel id="avalanches" typeId="avalanches"/>
|
||||
<channel id="vague-submersion-icon" typeId="condition-icon">
|
||||
<label>Wave Submersion Icon</label>
|
||||
</channel>
|
||||
<channel id="vent-icon" typeId="condition-icon">
|
||||
<label>Wind Icon</label>
|
||||
</channel>
|
||||
<channel id="pluie-inondation-icon" typeId="condition-icon">
|
||||
<label>Rain Flood Icon</label>
|
||||
</channel>
|
||||
<channel id="orage-icon" typeId="condition-icon">
|
||||
<label>Storm Icon</label>
|
||||
</channel>
|
||||
<channel id="inondation-icon" typeId="condition-icon">
|
||||
<label>Flood Icon</label>
|
||||
</channel>
|
||||
<channel id="neige-icon" typeId="condition-icon">
|
||||
<label>Snow Icon</label>
|
||||
</channel>
|
||||
<channel id="canicule-icon" typeId="condition-icon">
|
||||
<label>Heat Wave Icon</label>
|
||||
</channel>
|
||||
<channel id="grand-froid-icon" typeId="condition-icon">
|
||||
<label>Extreme Cold Icon</label>
|
||||
</channel>
|
||||
<channel id="avalanches-icon" typeId="condition-icon">
|
||||
<label>Avalanche Icon</label>
|
||||
</channel>
|
||||
<channel id="comment" typeId="comment"/>
|
||||
<channel id="observation-time" typeId="timestamp">
|
||||
<label>Start of Validity</label>
|
||||
</channel>
|
||||
<channel id="end-time" typeId="timestamp">
|
||||
<label>End of Validity</label>
|
||||
</channel>
|
||||
</channels>
|
||||
|
||||
<representation-property>department</representation-property>
|
||||
|
||||
<config-description>
|
||||
<parameter name="department" type="text" required="true">
|
||||
<label>Department</label>
|
||||
<description>Name of the department</description>
|
||||
<options>
|
||||
<option value="01">Ain</option>
|
||||
<option value="02">Aisne</option>
|
||||
<option value="03">Allier</option>
|
||||
<option value="04">Alpes de Haute Provence</option>
|
||||
<option value="06">Alpes Maritimes</option>
|
||||
<option value="07">Ardèche</option>
|
||||
<option value="08">Ardennes</option>
|
||||
<option value="09">Ariège</option>
|
||||
<option value="10">Aube</option>
|
||||
<option value="11">Aude</option>
|
||||
<option value="12">Aveyron</option>
|
||||
<option value="67">Bas-Rhin</option>
|
||||
<option value="13">Bouches du Rhône</option>
|
||||
<option value="14">Calvados</option>
|
||||
<option value="15">Cantal</option>
|
||||
<option value="16">Charente</option>
|
||||
<option value="17">Charente Maritime</option>
|
||||
<option value="18">Cher</option>
|
||||
<option value="19">Corrèze</option>
|
||||
<option value="2A">Corse du Sud</option>
|
||||
<option value="21">Côte D'Or</option>
|
||||
<option value="22">Côtes D'Armor</option>
|
||||
<option value="23">Creuse</option>
|
||||
<option value="79">Deux Sèvres</option>
|
||||
<option value="24">Dordogne</option>
|
||||
<option value="25">Doubs</option>
|
||||
<option value="26">Drôme</option>
|
||||
<option value="91">Essonne</option>
|
||||
<option value="27">Eure</option>
|
||||
<option value="28">Eure et Loir</option>
|
||||
<option value="29">Finistère</option>
|
||||
<option value="30">Gard</option>
|
||||
<option value="32">Gers</option>
|
||||
<option value="33">Gironde</option>
|
||||
<option value="68">Haut-Rhin</option>
|
||||
<option value="2B">Haute Corse</option>
|
||||
<option value="31">Haute Garonne</option>
|
||||
<option value="43">Haute Loire</option>
|
||||
<option value="52">Haute Marne</option>
|
||||
<option value="70">Haute Saône</option>
|
||||
<option value="74">Haute Savoie</option>
|
||||
<option value="87">Haute Vienne</option>
|
||||
<option value="05">Hautes Alpes</option>
|
||||
<option value="65">Hautes Pyrénées</option>
|
||||
<option value="92">Hauts de Seine</option>
|
||||
<option value="34">Hérault</option>
|
||||
<option value="35">Ille et Vilaine</option>
|
||||
<option value="36">Indre</option>
|
||||
<option value="37">Indre et Loire</option>
|
||||
<option value="38">Isère</option>
|
||||
<option value="39">Jura</option>
|
||||
<option value="40">Landes</option>
|
||||
<option value="41">Loir et Cher</option>
|
||||
<option value="42">Loire</option>
|
||||
<option value="44">Loire Atlantique</option>
|
||||
<option value="45">Loiret</option>
|
||||
<option value="46">Lot</option>
|
||||
<option value="47">Lot et Garonne</option>
|
||||
<option value="48">Lozère</option>
|
||||
<option value="49">Maine et Loire</option>
|
||||
<option value="50">Manche</option>
|
||||
<option value="51">Marne</option>
|
||||
<option value="53">Mayenne</option>
|
||||
<option value="54">Meurthe et Moselle</option>
|
||||
<option value="55">Meuse</option>
|
||||
<option value="56">Morbihan</option>
|
||||
<option value="57">Moselle</option>
|
||||
<option value="58">Nièvre</option>
|
||||
<option value="59">Nord</option>
|
||||
<option value="60">Oise</option>
|
||||
<option value="61">Orne</option>
|
||||
<option value="75">Paris</option>
|
||||
<option value="62">Pas de Calais</option>
|
||||
<option value="63">Puy de Dôme</option>
|
||||
<option value="64">Pyrénées Atlantiques</option>
|
||||
<option value="66">Pyrénées Orientales</option>
|
||||
<option value="69">Rhône</option>
|
||||
<option value="71">Saône et Loire</option>
|
||||
<option value="72">Sarthe</option>
|
||||
<option value="73">Savoie</option>
|
||||
<option value="77">Seine et Marne</option>
|
||||
<option value="76">Seine Maritime</option>
|
||||
<option value="93">Seine Saint Denis</option>
|
||||
<option value="80">Somme</option>
|
||||
<option value="81">Tarn</option>
|
||||
<option value="82">Tarn et Garonne</option>
|
||||
<option value="90">Territoire de Belfort</option>
|
||||
<option value="95">Val D'Oise</option>
|
||||
<option value="94">Val de Marne</option>
|
||||
<option value="83">Var</option>
|
||||
<option value="84">Vaucluse</option>
|
||||
<option value="85">Vendée</option>
|
||||
<option value="86">Vienne</option>
|
||||
<option value="88">Vosges</option>
|
||||
<option value="89">Yonne</option>
|
||||
<option value="78">Yvelines</option>
|
||||
</options>
|
||||
<limitToOptions>true</limitToOptions>
|
||||
</parameter>
|
||||
<parameter name="refresh" type="integer" min="1" required="true" unit="min">
|
||||
<label>Refresh Rate</label>
|
||||
<description>Data refresh period in minutes.</description>
|
||||
<default>60</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
@ -0,0 +1,770 @@
|
||||
[
|
||||
{
|
||||
"id": "01",
|
||||
"name": "Ain",
|
||||
"northest_lat": 46.517199374492,
|
||||
"southest_lat": 45.611235124481,
|
||||
"eastest_lon": 6.1697363568789,
|
||||
"westest_lon": 4.729097034294
|
||||
},
|
||||
{
|
||||
"id": "02",
|
||||
"name": "Aisne",
|
||||
"northest_lat": 50.069271974234,
|
||||
"southest_lat": 48.837795469902,
|
||||
"eastest_lon": 4.2540638814402,
|
||||
"westest_lon": 2.9624508927558
|
||||
},
|
||||
{
|
||||
"id": "03",
|
||||
"name": "Allier",
|
||||
"northest_lat": 46.803872076205,
|
||||
"southest_lat": 45.930727869968,
|
||||
"eastest_lon": 4.0055701432229,
|
||||
"westest_lon": 2.2804029533754
|
||||
},
|
||||
{
|
||||
"id": "04",
|
||||
"name": "Alpes-de-Haute-Provence",
|
||||
"northest_lat": 44.659501345682,
|
||||
"southest_lat": 43.668282105491,
|
||||
"eastest_lon": 6.9668199032047,
|
||||
"westest_lon": 5.4980104773442
|
||||
},
|
||||
{
|
||||
"id": "05",
|
||||
"name": "Hautes-Alpes",
|
||||
"northest_lat": 45.12684420383,
|
||||
"southest_lat": 44.186478874057,
|
||||
"eastest_lon": 7.0771048243018,
|
||||
"westest_lon": 5.4185330627929
|
||||
},
|
||||
{
|
||||
"id": "06",
|
||||
"name": "Alpes-Maritimes",
|
||||
"northest_lat": 44.361051257141,
|
||||
"southest_lat": 43.480065494401,
|
||||
"eastest_lon": 7.7169378581589,
|
||||
"westest_lon": 6.6363906079569
|
||||
},
|
||||
{
|
||||
"id": "07",
|
||||
"name": "Ardèche",
|
||||
"northest_lat": 45.365674921417,
|
||||
"southest_lat": 44.264783733394,
|
||||
"eastest_lon": 4.8865943991285,
|
||||
"westest_lon": 3.8615128126047
|
||||
},
|
||||
{
|
||||
"id": "08",
|
||||
"name": "Ardennes",
|
||||
"northest_lat": 50.168317417174,
|
||||
"southest_lat": 49.228510768771,
|
||||
"eastest_lon": 5.3935393812988,
|
||||
"westest_lon": 4.0252899216328
|
||||
},
|
||||
{
|
||||
"id": "09",
|
||||
"name": "Ariège",
|
||||
"northest_lat": 43.315601482419,
|
||||
"southest_lat": 42.572397819345,
|
||||
"eastest_lon": 2.1758766074869,
|
||||
"westest_lon": 0.82612266137771
|
||||
},
|
||||
{
|
||||
"id": "10",
|
||||
"name": "Aube",
|
||||
"northest_lat": 48.716672523486,
|
||||
"southest_lat": 47.924112631788,
|
||||
"eastest_lon": 4.863174195777,
|
||||
"westest_lon": 3.3883584814447
|
||||
},
|
||||
{
|
||||
"id": "11",
|
||||
"name": "Aude",
|
||||
"northest_lat": 43.459927734352,
|
||||
"southest_lat": 42.64890098195,
|
||||
"eastest_lon": 3.2405623482295,
|
||||
"westest_lon": 1.6884233932357
|
||||
},
|
||||
{
|
||||
"id": "12",
|
||||
"name": "Aveyron",
|
||||
"northest_lat": 44.941219492647,
|
||||
"southest_lat": 43.692056102371,
|
||||
"eastest_lon": 3.4507554815828,
|
||||
"westest_lon": 1.8396044963184
|
||||
},
|
||||
{
|
||||
"id": "13",
|
||||
"name": "Bouches-du-Rhône",
|
||||
"northest_lat": 43.92406219253,
|
||||
"southest_lat": 43.162545513212,
|
||||
"eastest_lon": 5.8132476569219,
|
||||
"westest_lon": 4.2302808850321
|
||||
},
|
||||
{
|
||||
"id": "14",
|
||||
"name": "Calvados",
|
||||
"northest_lat": 49.429859840723,
|
||||
"southest_lat": 48.752223582274,
|
||||
"eastest_lon": 0.44627431224134,
|
||||
"westest_lon": -1.1595014604014
|
||||
},
|
||||
{
|
||||
"id": "15",
|
||||
"name": "Cantal",
|
||||
"northest_lat": 45.480702895801,
|
||||
"southest_lat": 44.61552895784,
|
||||
"eastest_lon": 3.3699091459722,
|
||||
"westest_lon": 2.0629079799591
|
||||
},
|
||||
{
|
||||
"id": "16",
|
||||
"name": "Charente",
|
||||
"northest_lat": 46.139591492141,
|
||||
"southest_lat": 45.191628193392,
|
||||
"eastest_lon": 0.9456207917489,
|
||||
"westest_lon": -0.46177341555077
|
||||
},
|
||||
{
|
||||
"id": "17",
|
||||
"name": "Charente-Maritime",
|
||||
"northest_lat": 46.371051399922,
|
||||
"southest_lat": 45.088810634907,
|
||||
"eastest_lon": 0.005823224821197,
|
||||
"westest_lon": -1.5614800452621
|
||||
},
|
||||
{
|
||||
"id": "18",
|
||||
"name": "Cher",
|
||||
"northest_lat": 47.628965936616,
|
||||
"southest_lat": 46.420403547753,
|
||||
"eastest_lon": 3.0793324170792,
|
||||
"westest_lon": 1.7745852665449
|
||||
},
|
||||
{
|
||||
"id": "19",
|
||||
"name": "Corrèze",
|
||||
"northest_lat": 45.763895555756,
|
||||
"southest_lat": 44.923721627249,
|
||||
"eastest_lon": 2.5283596411119,
|
||||
"westest_lon": 1.2271245972559
|
||||
},
|
||||
{
|
||||
"id": "21",
|
||||
"name": "Côte-d'Or",
|
||||
"northest_lat": 48.030241950581,
|
||||
"southest_lat": 46.900857518168,
|
||||
"eastest_lon": 5.5185372800929,
|
||||
"westest_lon": 4.0660574486622
|
||||
},
|
||||
{
|
||||
"id": "22",
|
||||
"name": "Côtes-d'Armor",
|
||||
"northest_lat": 48.867411825697,
|
||||
"southest_lat": 48.035478415172,
|
||||
"eastest_lon": -1.9089921410274,
|
||||
"westest_lon": -3.663669588163
|
||||
},
|
||||
{
|
||||
"id": "23",
|
||||
"name": "Creuse",
|
||||
"northest_lat": 46.45481310551,
|
||||
"southest_lat": 45.664008285608,
|
||||
"eastest_lon": 2.6107853057918,
|
||||
"westest_lon": 1.3748978470741
|
||||
},
|
||||
{
|
||||
"id": "24",
|
||||
"name": "Dordogne",
|
||||
"northest_lat": 45.714569962764,
|
||||
"southest_lat": 44.57129825478,
|
||||
"eastest_lon": 1.4482602497483,
|
||||
"westest_lon": -0.041998525054412
|
||||
},
|
||||
{
|
||||
"id": "25",
|
||||
"name": "Doubs",
|
||||
"northest_lat": 47.579897594928,
|
||||
"southest_lat": 46.553996454277,
|
||||
"eastest_lon": 7.0622006908671,
|
||||
"westest_lon": 5.6987272452696
|
||||
},
|
||||
{
|
||||
"id": "26",
|
||||
"name": "Drôme",
|
||||
"northest_lat": 45.344042230781,
|
||||
"southest_lat": 44.115716677493,
|
||||
"eastest_lon": 5.8294720463131,
|
||||
"westest_lon": 4.6477668446587
|
||||
},
|
||||
{
|
||||
"id": "27",
|
||||
"name": "Eure",
|
||||
"northest_lat": 49.485111873749,
|
||||
"southest_lat": 48.666521479531,
|
||||
"eastest_lon": 1.8026740663848,
|
||||
"westest_lon": 0.29722451460974
|
||||
},
|
||||
{
|
||||
"id": "28",
|
||||
"name": "Eure-et-Loir",
|
||||
"northest_lat": 48.941051842112,
|
||||
"southest_lat": 47.953852019595,
|
||||
"eastest_lon": 1.9940901445311,
|
||||
"westest_lon": 0.76023175104941
|
||||
},
|
||||
{
|
||||
"id": "29",
|
||||
"name": "Finistère",
|
||||
"northest_lat": 48.75230874743,
|
||||
"southest_lat": 47.762638930067,
|
||||
"eastest_lon": -3.3880788564101,
|
||||
"westest_lon": -5.138001239929
|
||||
},
|
||||
{
|
||||
"id": "30",
|
||||
"name": "Gard",
|
||||
"northest_lat": 44.459798467391,
|
||||
"southest_lat": 43.460183661653,
|
||||
"eastest_lon": 4.8455501032842,
|
||||
"westest_lon": 3.2628340569911
|
||||
},
|
||||
{
|
||||
"id": "31",
|
||||
"name": "Haute-Garonne",
|
||||
"northest_lat": 43.920240096152,
|
||||
"southest_lat": 42.68989270234,
|
||||
"eastest_lon": 2.0478554672695,
|
||||
"westest_lon": 0.44199364903152
|
||||
},
|
||||
{
|
||||
"id": "32",
|
||||
"name": "Gers",
|
||||
"northest_lat": 44.078224550392,
|
||||
"southest_lat": 43.310884111508,
|
||||
"eastest_lon": 1.2013345895525,
|
||||
"westest_lon": -0.28211623210758
|
||||
},
|
||||
{
|
||||
"id": "33",
|
||||
"name": "Gironde",
|
||||
"northest_lat": 45.574691325999,
|
||||
"southest_lat": 44.193811119459,
|
||||
"eastest_lon": 0.31506020240148,
|
||||
"westest_lon": -1.2617334302552
|
||||
},
|
||||
{
|
||||
"id": "34",
|
||||
"name": "Hérault",
|
||||
"northest_lat": 43.969527164685,
|
||||
"southest_lat": 43.212804132866,
|
||||
"eastest_lon": 4.1944474773799,
|
||||
"westest_lon": 2.5399656073586
|
||||
},
|
||||
{
|
||||
"id": "35",
|
||||
"name": "Ille-et-Vilaine",
|
||||
"northest_lat": 48.704854504824,
|
||||
"southest_lat": 47.631356309182,
|
||||
"eastest_lon": -1.0168893967587,
|
||||
"westest_lon": -2.289084836122
|
||||
},
|
||||
{
|
||||
"id": "36",
|
||||
"name": "Indre",
|
||||
"northest_lat": 47.276819032313,
|
||||
"southest_lat": 46.347214822447,
|
||||
"eastest_lon": 2.2043920861378,
|
||||
"westest_lon": 0.86746898682573
|
||||
},
|
||||
{
|
||||
"id": "37",
|
||||
"name": "Indre-et-Loire",
|
||||
"northest_lat": 47.709346222795,
|
||||
"southest_lat": 46.737086924375,
|
||||
"eastest_lon": 1.3653663291974,
|
||||
"westest_lon": 0.053277684947378
|
||||
},
|
||||
{
|
||||
"id": "38",
|
||||
"name": "Isère",
|
||||
"northest_lat": 45.883269928025,
|
||||
"southest_lat": 44.696067584965,
|
||||
"eastest_lon": 6.3588423781754,
|
||||
"westest_lon": 4.7441167394752
|
||||
},
|
||||
{
|
||||
"id": "39",
|
||||
"name": "Jura",
|
||||
"northest_lat": 47.305475313171,
|
||||
"southest_lat": 46.260731935709,
|
||||
"eastest_lon": 6.2033299339615,
|
||||
"westest_lon": 5.2548827302617
|
||||
},
|
||||
{
|
||||
"id": "40",
|
||||
"name": "Landes",
|
||||
"northest_lat": 44.532195517275,
|
||||
"southest_lat": 43.487949116697,
|
||||
"eastest_lon": 0.13672631290526,
|
||||
"westest_lon": -1.524870110434
|
||||
},
|
||||
{
|
||||
"id": "41",
|
||||
"name": "Loir-et-Cher",
|
||||
"northest_lat": 48.132548568904,
|
||||
"southest_lat": 47.18622172903,
|
||||
"eastest_lon": 2.2478931361182,
|
||||
"westest_lon": 0.58052041667909
|
||||
},
|
||||
{
|
||||
"id": "42",
|
||||
"name": "Loire",
|
||||
"northest_lat": 46.275936357353,
|
||||
"southest_lat": 45.232177394436,
|
||||
"eastest_lon": 4.7604638818845,
|
||||
"westest_lon": 3.6906909501902
|
||||
},
|
||||
{
|
||||
"id": "43",
|
||||
"name": "Haute-Loire",
|
||||
"northest_lat": 45.427582294546,
|
||||
"southest_lat": 44.743866105932,
|
||||
"eastest_lon": 4.489606977621,
|
||||
"westest_lon": 3.0822533822787
|
||||
},
|
||||
{
|
||||
"id": "44",
|
||||
"name": "Loire-Atlantique",
|
||||
"northest_lat": 47.833557723029,
|
||||
"southest_lat": 46.860078088448,
|
||||
"eastest_lon": -0.94643916329696,
|
||||
"westest_lon": -2.5589448655806
|
||||
},
|
||||
{
|
||||
"id": "45",
|
||||
"name": "Loiret",
|
||||
"northest_lat": 48.344598562828,
|
||||
"southest_lat": 47.482968445146,
|
||||
"eastest_lon": 3.1284487900515,
|
||||
"westest_lon": 1.5129691249084
|
||||
},
|
||||
{
|
||||
"id": "46",
|
||||
"name": "Lot",
|
||||
"northest_lat": 45.046275852749,
|
||||
"southest_lat": 44.204018679795,
|
||||
"eastest_lon": 2.2108934010391,
|
||||
"westest_lon": 0.98177646477517
|
||||
},
|
||||
{
|
||||
"id": "47",
|
||||
"name": "Lot-et-Garonne",
|
||||
"northest_lat": 44.764390535693,
|
||||
"southest_lat": 43.973860568873,
|
||||
"eastest_lon": 1.0779367166615,
|
||||
"westest_lon": -0.14068987994571
|
||||
},
|
||||
{
|
||||
"id": "48",
|
||||
"name": "Lozère",
|
||||
"northest_lat": 44.971408091786,
|
||||
"southest_lat": 44.113818175271,
|
||||
"eastest_lon": 3.9981617468281,
|
||||
"westest_lon": 2.981675726654
|
||||
},
|
||||
{
|
||||
"id": "49",
|
||||
"name": "Maine-et-Loire",
|
||||
"northest_lat": 47.809992506553,
|
||||
"southest_lat": 46.969397597368,
|
||||
"eastest_lon": 0.23453049018557,
|
||||
"westest_lon": -1.3541992398083
|
||||
},
|
||||
{
|
||||
"id": "50",
|
||||
"name": "Manche",
|
||||
"northest_lat": 49.725557927402,
|
||||
"southest_lat": 48.458282754255,
|
||||
"eastest_lon": -0.73732101904671,
|
||||
"westest_lon": -1.9472733176655
|
||||
},
|
||||
{
|
||||
"id": "51",
|
||||
"name": "Marne",
|
||||
"northest_lat": 49.406179032892,
|
||||
"southest_lat": 48.516108006569,
|
||||
"eastest_lon": 5.0379027924329,
|
||||
"westest_lon": 3.398657955437
|
||||
},
|
||||
{
|
||||
"id": "52",
|
||||
"name": "Haute-Marne",
|
||||
"northest_lat": 48.688711618117,
|
||||
"southest_lat": 47.576950536437,
|
||||
"eastest_lon": 5.8908642780035,
|
||||
"westest_lon": 4.6268310932286
|
||||
},
|
||||
{
|
||||
"id": "53",
|
||||
"name": "Mayenne",
|
||||
"northest_lat": 48.567994064435,
|
||||
"southest_lat": 47.733379704738,
|
||||
"eastest_lon": -0.049909790963035,
|
||||
"westest_lon": -1.238247803597
|
||||
},
|
||||
{
|
||||
"id": "54",
|
||||
"name": "Meurthe-et-Moselle",
|
||||
"northest_lat": 49.562644003065,
|
||||
"southest_lat": 48.349889737943,
|
||||
"eastest_lon": 7.1231636635608,
|
||||
"westest_lon": 5.429907860027
|
||||
},
|
||||
{
|
||||
"id": "55",
|
||||
"name": "Meuse",
|
||||
"northest_lat": 49.617086785829,
|
||||
"southest_lat": 48.410687855212,
|
||||
"eastest_lon": 5.8541770017029,
|
||||
"westest_lon": 4.8885820531146
|
||||
},
|
||||
{
|
||||
"id": "56",
|
||||
"name": "Morbihan",
|
||||
"northest_lat": 48.210884763611,
|
||||
"southest_lat": 47.283069445657,
|
||||
"eastest_lon": -2.0357552590146,
|
||||
"westest_lon": -3.7321436369252
|
||||
},
|
||||
{
|
||||
"id": "57",
|
||||
"name": "Moselle",
|
||||
"northest_lat": 49.510019040716,
|
||||
"southest_lat": 48.52694525177,
|
||||
"eastest_lon": 7.6352815933424,
|
||||
"westest_lon": 5.8934039932125
|
||||
},
|
||||
{
|
||||
"id": "58",
|
||||
"name": "Nièvre",
|
||||
"northest_lat": 47.587958865747,
|
||||
"southest_lat": 46.651760006926,
|
||||
"eastest_lon": 4.2306617272065,
|
||||
"westest_lon": 2.8451871650071
|
||||
},
|
||||
{
|
||||
"id": "59",
|
||||
"name": "Nord",
|
||||
"northest_lat": 51.08854370897,
|
||||
"southest_lat": 49.969186662527,
|
||||
"eastest_lon": 4.2279959931456,
|
||||
"westest_lon": 2.0677049871716
|
||||
},
|
||||
{
|
||||
"id": "60",
|
||||
"name": "Oise",
|
||||
"northest_lat": 49.758309270134,
|
||||
"southest_lat": 49.060452516659,
|
||||
"eastest_lon": 3.162641421643,
|
||||
"westest_lon": 1.6895744511517
|
||||
},
|
||||
{
|
||||
"id": "61",
|
||||
"name": "Orne",
|
||||
"northest_lat": 48.972557592954,
|
||||
"southest_lat": 48.181599665308,
|
||||
"eastest_lon": 0.9762713097259,
|
||||
"westest_lon": -0.86036021134895
|
||||
},
|
||||
{
|
||||
"id": "62",
|
||||
"name": "Pas-de-Calais",
|
||||
"northest_lat": 51.006501514321,
|
||||
"southest_lat": 50.020975633738,
|
||||
"eastest_lon": 3.1883563131291,
|
||||
"westest_lon": 1.5577948179294
|
||||
},
|
||||
{
|
||||
"id": "63",
|
||||
"name": "Puy-de-Dôme",
|
||||
"northest_lat": 46.255486133208,
|
||||
"southest_lat": 45.287121578381,
|
||||
"eastest_lon": 3.9844000097893,
|
||||
"westest_lon": 2.388014020679
|
||||
},
|
||||
{
|
||||
"id": "64",
|
||||
"name": "Pyrénées-Atlantiques",
|
||||
"northest_lat": 43.596401195938,
|
||||
"southest_lat": 42.777515930774,
|
||||
"eastest_lon": 0.02629551293813,
|
||||
"westest_lon": -1.7908870919282
|
||||
},
|
||||
{
|
||||
"id": "65",
|
||||
"name": "Hautes-Pyrénées",
|
||||
"northest_lat": 43.609311711216,
|
||||
"southest_lat": 42.674921018438,
|
||||
"eastest_lon": 0.64553925526757,
|
||||
"westest_lon": -0.3270823405503
|
||||
},
|
||||
{
|
||||
"id": "66",
|
||||
"name": "Pyrénées-Orientales",
|
||||
"northest_lat": 42.918339638726,
|
||||
"southest_lat": 42.33364688988,
|
||||
"eastest_lon": 3.1747892794105,
|
||||
"westest_lon": 1.7256472450279
|
||||
},
|
||||
{
|
||||
"id": "67",
|
||||
"name": "Bas-Rhin",
|
||||
"northest_lat": 49.077884925649,
|
||||
"southest_lat": 48.120371112534,
|
||||
"eastest_lon": 8.2303986615424,
|
||||
"westest_lon": 6.9403717864006
|
||||
},
|
||||
{
|
||||
"id": "68",
|
||||
"name": "Haut-Rhin",
|
||||
"northest_lat": 48.310471263573,
|
||||
"southest_lat": 47.422198455938,
|
||||
"eastest_lon": 7.6220859200517,
|
||||
"westest_lon": 6.8428287756472
|
||||
},
|
||||
{
|
||||
"id": "69",
|
||||
"name": "Rhône",
|
||||
"northest_lat": 46.303994122044,
|
||||
"southest_lat": 45.45503324486,
|
||||
"eastest_lon": 5.1592030475156,
|
||||
"westest_lon": 4.243469905983
|
||||
},
|
||||
{
|
||||
"id": "70",
|
||||
"name": "Haute-Saône",
|
||||
"northest_lat": 48.023714993889,
|
||||
"southest_lat": 47.253139353829,
|
||||
"eastest_lon": 6.8235333222471,
|
||||
"westest_lon": 5.3727580571009
|
||||
},
|
||||
{
|
||||
"id": "71",
|
||||
"name": "Saône-et-Loire",
|
||||
"northest_lat": 47.155410810959,
|
||||
"southest_lat": 46.156946471815,
|
||||
"eastest_lon": 5.4622983197648,
|
||||
"westest_lon": 3.6225898833129
|
||||
},
|
||||
{
|
||||
"id": "72",
|
||||
"name": "Sarthe",
|
||||
"northest_lat": 48.482954540393,
|
||||
"southest_lat": 47.569104805534,
|
||||
"eastest_lon": 0.91379809767445,
|
||||
"westest_lon": -0.44786007819229
|
||||
},
|
||||
{
|
||||
"id": "73",
|
||||
"name": "Savoie",
|
||||
"northest_lat": 45.93845768164,
|
||||
"southest_lat": 45.051837207667,
|
||||
"eastest_lon": 7.1842712160815,
|
||||
"westest_lon": 5.6230208703548
|
||||
},
|
||||
{
|
||||
"id": "74",
|
||||
"name": "Haute-Savoie",
|
||||
"northest_lat": 46.408081546332,
|
||||
"southest_lat": 45.682198985672,
|
||||
"eastest_lon": 7.0438913499404,
|
||||
"westest_lon": 5.8074048290847
|
||||
},
|
||||
{
|
||||
"id": "75",
|
||||
"name": "Paris",
|
||||
"northest_lat": 48.902007785215,
|
||||
"southest_lat": 48.816314210034,
|
||||
"eastest_lon": 2.4675819883673,
|
||||
"westest_lon": 2.2242191058804
|
||||
},
|
||||
{
|
||||
"id": "76",
|
||||
"name": "Seine-Maritime",
|
||||
"northest_lat": 50.070851596042,
|
||||
"southest_lat": 49.252262168305,
|
||||
"eastest_lon": 1.79022549105,
|
||||
"westest_lon": 0.065609431053556
|
||||
},
|
||||
{
|
||||
"id": "77",
|
||||
"name": "Seine-et-Marne",
|
||||
"northest_lat": 49.11755332218,
|
||||
"southest_lat": 48.122204261229,
|
||||
"eastest_lon": 3.555613758785,
|
||||
"westest_lon": 2.3931765378081
|
||||
},
|
||||
{
|
||||
"id": "78",
|
||||
"name": "Yvelines",
|
||||
"northest_lat": 49.08303659502,
|
||||
"southest_lat": 48.440146719021,
|
||||
"eastest_lon": 2.2265538842831,
|
||||
"westest_lon": 1.4472851104304
|
||||
},
|
||||
{
|
||||
"id": "79",
|
||||
"name": "Deux-Sèvres",
|
||||
"northest_lat": 47.108333434925,
|
||||
"southest_lat": 45.969661749473,
|
||||
"eastest_lon": 0.22035828616308,
|
||||
"westest_lon": -0.89196408624284
|
||||
},
|
||||
{
|
||||
"id": "80",
|
||||
"name": "Somme",
|
||||
"northest_lat": 50.366290636763,
|
||||
"southest_lat": 49.571762327,
|
||||
"eastest_lon": 3.2030417908111,
|
||||
"westest_lon": 1.3796981484469
|
||||
},
|
||||
{
|
||||
"id": "81",
|
||||
"name": "Tarn",
|
||||
"northest_lat": 44.200834436147,
|
||||
"southest_lat": 43.383508824887,
|
||||
"eastest_lon": 2.93545676901,
|
||||
"westest_lon": 1.5439759556659
|
||||
},
|
||||
{
|
||||
"id": "82",
|
||||
"name": "Tarn-et-Garonne",
|
||||
"northest_lat": 44.393331095059,
|
||||
"southest_lat": 43.770780304363,
|
||||
"eastest_lon": 1.9963637896774,
|
||||
"westest_lon": 0.73810974125492
|
||||
},
|
||||
{
|
||||
"id": "83",
|
||||
"name": "Var",
|
||||
"northest_lat": 43.806770970879,
|
||||
"southest_lat": 42.982043008785,
|
||||
"eastest_lon": 6.9337211159516,
|
||||
"westest_lon": 5.6559638228901
|
||||
},
|
||||
{
|
||||
"id": "84",
|
||||
"name": "Vaucluse",
|
||||
"northest_lat": 44.431367227183,
|
||||
"southest_lat": 43.658685905188,
|
||||
"eastest_lon": 5.7573377215236,
|
||||
"westest_lon": 4.649227423465
|
||||
},
|
||||
{
|
||||
"id": "85",
|
||||
"name": "Vendée",
|
||||
"northest_lat": 47.083893903306,
|
||||
"southest_lat": 46.266566974958,
|
||||
"eastest_lon": -0.53779518169029,
|
||||
"westest_lon": -2.3987614706025
|
||||
},
|
||||
{
|
||||
"id": "86",
|
||||
"name": "Vienne",
|
||||
"northest_lat": 47.175754285742,
|
||||
"southest_lat": 46.049008552161,
|
||||
"eastest_lon": 1.2126877519811,
|
||||
"westest_lon": -0.1021158452812
|
||||
},
|
||||
{
|
||||
"id": "87",
|
||||
"name": "Haute-Vienne",
|
||||
"northest_lat": 46.401546863371,
|
||||
"southest_lat": 45.437356928582,
|
||||
"eastest_lon": 1.9094484810021,
|
||||
"westest_lon": 0.62974117909144
|
||||
},
|
||||
{
|
||||
"id": "88",
|
||||
"name": "Vosges",
|
||||
"northest_lat": 48.513587820739,
|
||||
"southest_lat": 47.813051201983,
|
||||
"eastest_lon": 7.1982872111206,
|
||||
"westest_lon": 5.3944755711529
|
||||
},
|
||||
{
|
||||
"id": "89",
|
||||
"name": "Yonne",
|
||||
"northest_lat": 48.39970411104,
|
||||
"southest_lat": 47.312769315752,
|
||||
"eastest_lon": 4.3403007872795,
|
||||
"westest_lon": 2.8487899744432
|
||||
},
|
||||
{
|
||||
"id": "90",
|
||||
"name": "Territoire de Belfort",
|
||||
"northest_lat": 47.824784354742,
|
||||
"southest_lat": 47.433371743667,
|
||||
"eastest_lon": 7.1398015507652,
|
||||
"westest_lon": 6.7576409592057
|
||||
},
|
||||
{
|
||||
"id": "91",
|
||||
"name": "Essonne",
|
||||
"northest_lat": 48.776101996393,
|
||||
"southest_lat": 48.284688606385,
|
||||
"eastest_lon": 2.5853737107586,
|
||||
"westest_lon": 1.9149199821626
|
||||
},
|
||||
{
|
||||
"id": "92",
|
||||
"name": "Hauts-de-Seine",
|
||||
"northest_lat": 48.950965864655,
|
||||
"southest_lat": 48.72948996497,
|
||||
"eastest_lon": 2.3363529889891,
|
||||
"westest_lon": 2.1458760215967
|
||||
},
|
||||
{
|
||||
"id": "93",
|
||||
"name": "Seine-Saint-Denis",
|
||||
"northest_lat": 49.012397786393,
|
||||
"southest_lat": 48.807437551952,
|
||||
"eastest_lon": 2.6025997962059,
|
||||
"westest_lon": 2.2882536989787
|
||||
},
|
||||
{
|
||||
"id": "94",
|
||||
"name": "Val-de-Marne",
|
||||
"northest_lat": 48.861405371284,
|
||||
"southest_lat": 48.688326690701,
|
||||
"eastest_lon": 2.6136517425679,
|
||||
"westest_lon": 2.3102224901101
|
||||
},
|
||||
{
|
||||
"id": "95",
|
||||
"name": "Val-d'Oise",
|
||||
"northest_lat": 49.232197221792,
|
||||
"southest_lat": 48.908679329899,
|
||||
"eastest_lon": 2.5905283926735,
|
||||
"westest_lon": 1.608798807603
|
||||
},
|
||||
{
|
||||
"id": "2A",
|
||||
"name": "Corse-du-Sud",
|
||||
"northest_lat": 42.381404942274,
|
||||
"southest_lat": 41.362164776515,
|
||||
"eastest_lon": 9.4073217319481,
|
||||
"westest_lon": 8.5401025407511
|
||||
},
|
||||
{
|
||||
"id": "2B",
|
||||
"name": "Haute-Corse",
|
||||
"northest_lat": 43.011724041684,
|
||||
"southest_lat": 41.832143660252,
|
||||
"eastest_lon": 9.5592262719626,
|
||||
"westest_lon": 8.5734085639674
|
||||
}
|
||||
]
|
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg enable-background="new 0 0 64 64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
|
||||
<ellipse style="stroke-width: 0px; stroke: rgb(0, 0, 0); fill:#3d3c3c;" cx="32" cy="32" rx="30" ry="30"/>
|
||||
<g transform="matrix(0.095654, 0, 0, 0.103801, 7.65905, -0.7645)" style="">
|
||||
<g>
|
||||
<path style="fill:#9B5C5C;" d="M277.259,58.637c-11.695-20.344-30.835-20.344-42.53,0L4.978,432.587 c-11.695,20.342-2.07,36.966,21.398,36.966h459.235c23.468,0,33.093-16.624,21.405-36.966L277.259,58.637z"/>
|
||||
<path style="fill:#9B5C5C;" d="M277.259,57.683c-11.695-20.328-30.835-20.328-42.53,0l-23.538,59.732l-32.538,31.78L4.978,432.587 c-11.695,20.342-2.07,36.966,21.398,36.966h459.235c23.468,0,33.093-16.624,21.405-36.966l-56.124-91.592l-84.06-104.052 L277.259,57.683z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#CBD0D8;" d="M426.629,226.272c-23.562,0-42.671,19.108-42.671,42.671c0,23.554,19.109,42.646,42.671,42.646 c23.545,0,42.654-19.093,42.654-42.646C469.283,245.381,450.174,226.272,426.629,226.272L426.629,226.272z"/>
|
||||
<path style="fill:#CBD0D8;" d="M394.63,226.272c0,5.89-4.766,10.671-10.672,10.671c-5.875,0-10.656-4.781-10.656-10.671 c0-5.875,4.781-10.656,10.656-10.656C389.864,215.616,394.63,220.397,394.63,226.272z"/>
|
||||
<path style="fill:#CBD0D8;" d="M426.629,204.944c0,5.891-4.781,10.672-10.671,10.672c-5.891,0-10.656-4.781-10.656-10.672 s4.766-10.655,10.656-10.655C421.848,194.289,426.629,199.054,426.629,204.944z"/>
|
||||
<path style="fill:#CBD0D8;" d="M383.958,183.617c0,5.891-4.766,10.672-10.656,10.672s-10.656-4.781-10.656-10.672 s4.766-10.656,10.656-10.656S383.958,177.726,383.958,183.617z"/>
|
||||
<path style="fill:#CBD0D8;" d="M351.974,151.634c0,5.891-4.766,10.655-10.672,10.655c-5.874,0-10.655-4.765-10.655-10.655 s4.781-10.671,10.655-10.671C347.209,140.963,351.974,145.744,351.974,151.634z"/>
|
||||
</g>
|
||||
<path style="fill:#E6E9ED;" d="M 273.368 152.384 C 274.649 151.868 275.993 151.634 277.321 151.634 C 280.992 151.634 284.554 153.54 286.523 156.884 C 286.523 156.884 355.865 257.194 381.786 300.341 C 407.708 343.495 450.892 341.027 450.892 341.027 L 277.259 57.683 C 265.564 37.355 246.424 37.355 234.729 57.683 L 178.653 149.196 C 178.653 149.196 210.879 171.539 225.503 171.539 C 240.126 171.539 273.368 152.384 273.368 152.384 Z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg enable-background="new 0 0 64 64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
|
||||
<ellipse style="stroke-width: 0px; stroke: rgb(0, 0, 0); fill:#3d3c3c;" cx="32" cy="32" rx="30" ry="30" />
|
||||
<g fill="#dae1e4">
|
||||
<circle cx="32" cy="55" r="9" />
|
||||
<circle cx="32" cy="6" r="6" />
|
||||
</g>
|
||||
<circle cx="32" cy="6" r="5" fill="#d20014" />
|
||||
<path d="m26 6h12v50h-12z" fill="#dae1e4" />
|
||||
<g fill="#d20014">
|
||||
<path d="m27 6h10v48.94h-10z" />
|
||||
<circle cx="32" cy="55" r="8" />
|
||||
</g>
|
||||
<g fill="#fff">
|
||||
<path d="m33 9h5v2h-5z" />
|
||||
<path d="m33 17h5v2h-5z" />
|
||||
<path d="m33 25h5v2h-5z" />
|
||||
<path d="m33 33h5v2h-5z" />
|
||||
<path d="m33 41h5v2h-5z" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 759 B |
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg enable-background="new 0 0 64 64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
|
||||
<ellipse style="stroke-width: 0px; stroke: rgb(0, 0, 0); fill:#3d3c3c;" cx="32" cy="32" rx="30" ry="30" />
|
||||
<circle cx="32" cy="6" r="6" fill="#dae1e4" />
|
||||
<circle cx="32" cy="6" r="5" fill="#c4cacc" />
|
||||
<path d="m26 6h12v50h-12z" fill="#dae1e4" />
|
||||
<path d="m27 6h10v48.94h-10z" fill="#c4cacc" />
|
||||
<circle cx="32" cy="55" r="9" fill="#dae1e4" />
|
||||
<g fill="#2e7de5">
|
||||
<circle cx="32" cy="55" r="8" />
|
||||
<path d="m27 39h10v12h-10z" />
|
||||
</g>
|
||||
<g fill="#fff">
|
||||
<path d="m33 9h5v2h-5z" />
|
||||
<path d="m33 17h5v2h-5z" />
|
||||
<path d="m33 25h5v2h-5z" />
|
||||
<path d="m33 33h5v2h-5z" />
|
||||
<path d="m33 41h5v2h-5z" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 802 B |
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg enable-background="new 0 0 64 64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
|
||||
<ellipse style="stroke-width: 0px; stroke: rgb(0, 0, 0); fill:#3d3c3c;" cx="32" cy="32" rx="30" ry="30"/>
|
||||
<path fill="#F8EFE0" d="M 11.018 52.475 L 11.018 31.819 C 7.317 33.065 4.779 29.687 7.284 26.959 C 7.325 26.916 7.371 26.873 7.425 26.837 L 30.938 10.768 C 31.242 10.522 31.712 10.497 32.05 10.727 L 55.617 26.768 C 55.654 26.793 55.688 26.819 55.72 26.851 C 56.812 27.879 57.084 29.019 56.82 29.983 C 56.692 30.449 56.434 30.88 56.071 31.238 C 55.708 31.596 55.249 31.867 54.735 32.029 C 53.911 32.288 52.931 32.281 51.937 31.869 L 51.937 51.358 C 43.944 54.785 42.3 46.755 42.28 46.918 C 41.461 53.613 28.847 53.227 26.809 48.767 C 26.439 47.958 26.67 47.804 26.141 47.766 C 23.045 47.544 22.868 55.347 11.018 52.475 Z M 51.987 12.422 L 51.987 20.469 L 44.911 16.382 L 44.911 12.422 L 51.987 12.422 Z" style=""/>
|
||||
<path fill="#D93133" d="M 11.018 31.819 C 10.054 32.144 9.151 32.151 8.401 31.927 C 7.816 31.754 7.322 31.444 6.959 31.043 C 6.596 30.643 6.366 30.156 6.295 29.618 C 6.188 28.785 6.472 27.843 7.284 26.959 C 7.325 26.916 7.371 26.873 7.425 26.837 L 30.938 10.768 C 31.242 10.522 31.712 10.497 32.05 10.727 L 55.617 26.768 C 55.654 26.793 55.688 26.819 55.72 26.851 C 56.812 27.879 57.084 29.019 56.82 29.983 C 56.692 30.449 56.434 30.88 56.071 31.238 C 55.708 31.596 55.249 31.867 54.735 32.029 C 53.911 32.288 52.931 32.281 51.937 31.869 L 49.63 30.982 C 49.63 30.618 33.464 19.43 31.679 18.213 C 29.788 19.473 13.326 30.571 13.326 31.04 L 11.018 31.819 Z M 51.987 12.422 L 51.987 20.469 L 44.911 16.382 L 44.911 12.422 L 51.987 12.422 Z" style=""/>
|
||||
<path fill="#313A58" d="M 31.595 25.496 C 33.228 25.496 34.711 26.081 35.784 27.021 C 36.861 27.963 37.526 29.076 37.526 30.503 L 37.526 35.325 L 25.662 35.325 L 25.662 30.503 C 25.662 29.073 26.33 27.961 27.404 27.021 C 28.479 26.081 29.963 25.496 31.595 25.496 Z" style=""/>
|
||||
<path fill="#ABB9BC" d="M 32.111 31.421 L 32.111 34.426 L 36.496 34.426 L 36.496 31.421 L 32.111 31.421 Z M 32.111 26.424 L 32.111 30.517 L 36.496 30.517 L 36.496 30.505 C 36.496 29.326 35.945 28.439 35.056 27.661 C 34.282 26.983 33.252 26.529 32.111 26.424 Z M 31.079 30.517 L 31.079 26.424 C 29.936 26.531 28.909 26.983 28.134 27.661 C 27.245 28.439 26.694 29.326 26.694 30.505 L 26.694 30.517 L 31.079 30.517 Z M 31.079 34.423 L 31.079 31.421 L 26.694 31.421 L 26.694 34.426 L 31.079 34.426 L 31.079 34.423 Z" style=""/>
|
||||
<path fill="#313A58" d="M 51.92 31.732 L 49.64 30.959 L 49.64 52.389 L 51.92 52.389 L 51.92 31.732 Z M 10.908 31.819 L 13.189 31.046 L 13.189 52.476 L 10.908 52.476 L 10.908 31.819 Z" style=""/>
|
||||
<path d="M 11.097 51.603 C 13.269 52.586 15.988 52.276 18.451 51.315 C 21.367 50.176 23.866 48.168 24.668 46.318 C 24.9 45.781 25.509 45.54 26.029 45.779 C 26.259 45.885 26.444 46.075 26.547 46.312 C 27.432 48.152 28.886 49.487 30.554 50.246 C 31.623 50.733 32.775 50.983 33.918 50.978 C 35.051 50.973 36.18 50.717 37.211 50.195 C 38.688 49.446 39.974 48.13 40.802 46.195 C 41.031 45.656 41.641 45.412 42.163 45.649 C 42.416 45.764 42.614 45.978 42.711 46.245 C 43.106 47.121 43.54 47.869 44.009 48.496 C 45.11 49.969 46.402 50.756 47.805 50.981 C 49.259 51.215 50.874 50.868 52.56 50.07 C 53.763 49.501 55 48.701 56.239 47.714 L 57.499 49.397 C 56.142 50.478 54.77 51.363 53.416 52.004 C 51.373 52.971 49.365 53.383 47.49 53.082 C 45.567 52.773 43.824 51.731 42.377 49.796 C 42.148 49.488 41.933 49.17 41.734 48.842 C 40.756 50.32 39.505 51.399 38.116 52.103 C 36.799 52.772 35.361 53.098 33.918 53.104 C 32.484 53.109 31.046 52.799 29.722 52.197 C 28.122 51.468 26.677 50.311 25.588 48.764 C 24.183 50.57 21.811 52.279 19.178 53.307 C 16.265 54.444 12.989 54.782 10.273 53.553 L 11.097 51.603 Z" style="fill: rgb(30, 130, 255);"/>
|
||||
<path d="M 10.92 57.018 C 13.092 58.001 15.811 57.691 18.274 56.73 C 21.19 55.591 23.689 53.583 24.491 51.733 C 24.723 51.196 25.332 50.955 25.852 51.194 C 26.082 51.3 26.267 51.49 26.37 51.727 C 27.255 53.567 28.709 54.902 30.377 55.661 C 31.446 56.148 32.598 56.398 33.741 56.393 C 34.874 56.388 36.003 56.132 37.034 55.61 C 38.511 54.861 39.797 53.545 40.625 51.61 C 40.854 51.071 41.464 50.827 41.986 51.064 C 42.239 51.179 42.437 51.393 42.534 51.66 C 42.929 52.536 43.363 53.284 43.832 53.911 C 44.933 55.384 46.225 56.171 47.628 56.396 C 49.082 56.63 50.697 56.283 52.383 55.485 C 53.586 54.916 54.823 54.116 56.062 53.129 L 57.322 54.812 C 55.965 55.893 54.593 56.778 53.239 57.419 C 51.196 58.386 49.188 58.798 47.313 58.497 C 45.39 58.188 43.647 57.146 42.2 55.211 C 41.971 54.903 41.756 54.585 41.557 54.257 C 40.579 55.735 39.328 56.814 37.939 57.518 C 36.622 58.187 35.184 58.513 33.741 58.519 C 32.307 58.524 30.869 58.214 29.545 57.612 C 27.945 56.883 26.5 55.726 25.411 54.179 C 24.006 55.985 21.634 57.694 19.001 58.722 C 16.088 59.859 12.812 60.197 10.096 58.968 L 10.92 57.018 Z" style="fill: rgb(30, 130, 255);"/>
|
||||
</svg>
|
After Width: | Height: | Size: 4.9 KiB |
@ -0,0 +1,81 @@
|
||||
<svg width="55" height="63" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="prefix__e">
|
||||
<feMorphology radius="2" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1" />
|
||||
<feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1" />
|
||||
<feGaussianBlur stdDeviation="1.5" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" in="shadowBlurOuter1" />
|
||||
</filter>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="prefix__g">
|
||||
<feMorphology radius="1.08" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1" />
|
||||
<feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1" />
|
||||
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" in="shadowBlurOuter1" />
|
||||
</filter>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="prefix__i">
|
||||
<feMorphology radius="1.44" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1" />
|
||||
<feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1" />
|
||||
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" in="shadowBlurOuter1" />
|
||||
</filter>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="prefix__k">
|
||||
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1" />
|
||||
<feGaussianBlur stdDeviation="1.5" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" in="shadowBlurOuter1" />
|
||||
</filter>
|
||||
<mask id="prefix__f" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-2" y="-2"
|
||||
width="27.056" height="36.375">
|
||||
<path fill="#fff" d="M9 21h27.056v36.375H9z" />
|
||||
<use xlink:href="#prefix__a" />
|
||||
</mask>
|
||||
<mask id="prefix__h" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-1.08" y="-1.08"
|
||||
width="14.41" height="19.66">
|
||||
<path fill="#fff" d="M2.92 3.92h14.41v19.66H2.92z" />
|
||||
<use xlink:href="#prefix__b" />
|
||||
</mask>
|
||||
<mask id="prefix__j" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-1.44" y="-1.44"
|
||||
width="19.505" height="26.505">
|
||||
<path fill="#fff" d="M25.56-1.44h19.505v26.505H25.56z" />
|
||||
<use xlink:href="#prefix__c" />
|
||||
</mask>
|
||||
<mask id="prefix__l" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="67"
|
||||
height="4" fill="#fff">
|
||||
<use xlink:href="#prefix__d" />
|
||||
</mask>
|
||||
<path
|
||||
d="M22.528 23C20.887 23 11 38.241 11 44.803c0 5.174 2.987 10.572 11.528 10.572 7.82 0 11.528-5.346 11.528-10.572C34.056 38.158 24.169 23 22.528 23z"
|
||||
id="prefix__a" />
|
||||
<path
|
||||
d="M10.125 5C9.253 5 4 13.238 4 16.785c0 2.797 1.587 5.715 6.125 5.715 4.155 0 6.125-2.89 6.125-5.715C16.25 13.193 10.997 5 10.125 5z"
|
||||
id="prefix__b" />
|
||||
<path
|
||||
d="M35.313 0C34.129 0 27 11.122 27 15.91c0 3.776 2.154 7.715 8.313 7.715 5.64 0 8.312-3.901 8.312-7.715 0-4.849-7.129-15.91-8.313-15.91z"
|
||||
id="prefix__c" />
|
||||
<rect id="prefix__d" x="-8.105" y="28.395" width="67" height="4" rx="2" />
|
||||
</defs>
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<g transform="translate(2 2)">
|
||||
<use fill="#000" filter="url(#prefix__e)" xlink:href="#prefix__a" />
|
||||
<use fill-opacity=".3" fill="#55A4FF" xlink:href="#prefix__a" />
|
||||
<use stroke="#FFF" mask="url(#prefix__f)" stroke-width="4" xlink:href="#prefix__a" />
|
||||
</g>
|
||||
<g transform="translate(2 2)">
|
||||
<use fill="#000" filter="url(#prefix__g)" xlink:href="#prefix__b" />
|
||||
<use fill-opacity=".3" fill="#55A4FF" xlink:href="#prefix__b" />
|
||||
<use stroke="#FFF" mask="url(#prefix__h)" stroke-width="2.16" xlink:href="#prefix__b" />
|
||||
</g>
|
||||
<g transform="translate(2 2)">
|
||||
<use fill="#000" filter="url(#prefix__i)" xlink:href="#prefix__c" />
|
||||
<use fill-opacity=".3" fill="#55A4FF" xlink:href="#prefix__c" />
|
||||
<use stroke="#FFF" mask="url(#prefix__j)" stroke-width="2.88" xlink:href="#prefix__c" />
|
||||
</g>
|
||||
<g transform="rotate(-45 28.81 28.981)">
|
||||
<use fill="#000" filter="url(#prefix__k)" xlink:href="#prefix__d" />
|
||||
<use stroke="#FFF" mask="url(#prefix__l)" stroke-width="2" fill="#464646" xlink:href="#prefix__d" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.4 KiB |
@ -0,0 +1,66 @@
|
||||
<svg width="46" height="63" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="prefix__d">
|
||||
<feMorphology radius="2" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1" />
|
||||
<feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1" />
|
||||
<feGaussianBlur stdDeviation="1.5" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" in="shadowBlurOuter1" />
|
||||
</filter>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="prefix__f">
|
||||
<feMorphology radius="1.08" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1" />
|
||||
<feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1" />
|
||||
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" in="shadowBlurOuter1" />
|
||||
</filter>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="prefix__h">
|
||||
<feMorphology radius="1.44" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1" />
|
||||
<feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1" />
|
||||
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" in="shadowBlurOuter1" />
|
||||
</filter>
|
||||
<path
|
||||
d="M18.528 23C16.887 23 7 38.241 7 44.803c0 5.174 2.987 10.572 11.528 10.572 7.82 0 11.528-5.346 11.528-10.572C30.056 38.158 20.169 23 18.528 23z"
|
||||
id="prefix__a" />
|
||||
<path
|
||||
d="M6.125 5C5.253 5 0 13.238 0 16.785 0 19.582 1.587 22.5 6.125 22.5c4.155 0 6.125-2.89 6.125-5.715C12.25 13.193 6.997 5 6.125 5z"
|
||||
id="prefix__b" />
|
||||
<path
|
||||
d="M31.313 0C30.128 0 23 11.122 23 15.91c0 3.776 2.154 7.715 8.313 7.715 5.64 0 8.312-3.901 8.312-7.715 0-4.849-7.129-15.91-8.313-15.91z"
|
||||
id="prefix__c" />
|
||||
<mask id="prefix__e" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-2" y="-2"
|
||||
width="27.056" height="36.375">
|
||||
<path fill="#fff" d="M5 21h27.056v36.375H5z" />
|
||||
<use xlink:href="#prefix__a" />
|
||||
</mask>
|
||||
<mask id="prefix__g" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-1.08" y="-1.08"
|
||||
width="14.41" height="19.66">
|
||||
<path fill="#fff" d="M-1.08 3.92h14.41v19.66H-1.08z" />
|
||||
<use xlink:href="#prefix__b" />
|
||||
</mask>
|
||||
<mask id="prefix__i" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-1.44" y="-1.44"
|
||||
width="19.505" height="26.505">
|
||||
<path fill="#fff" d="M21.56-1.44h19.505v26.505H21.56z" />
|
||||
<use xlink:href="#prefix__c" />
|
||||
</mask>
|
||||
</defs>
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<g transform="translate(3 2)">
|
||||
<use fill="#000" filter="url(#prefix__d)" xlink:href="#prefix__a" />
|
||||
<use fill-opacity=".3" fill="#55A4FF" xlink:href="#prefix__a" />
|
||||
<use stroke="#FFF" mask="url(#prefix__e)" stroke-width="4" xlink:href="#prefix__a" />
|
||||
</g>
|
||||
<g transform="translate(3 2)">
|
||||
<use fill="#000" filter="url(#prefix__f)" xlink:href="#prefix__b" />
|
||||
<use fill-opacity=".3" fill="#55A4FF" xlink:href="#prefix__b" />
|
||||
<use stroke="#FFF" mask="url(#prefix__g)" stroke-width="2.16" xlink:href="#prefix__b" />
|
||||
</g>
|
||||
<g transform="translate(3 2)">
|
||||
<use fill="#000" filter="url(#prefix__h)" xlink:href="#prefix__c" />
|
||||
<use fill="#55A4FF" xlink:href="#prefix__c" />
|
||||
<use stroke="#FFF" mask="url(#prefix__i)" stroke-width="2.88" xlink:href="#prefix__c" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.3 KiB |
@ -0,0 +1,66 @@
|
||||
<svg width="46" height="63" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="prefix__d">
|
||||
<feMorphology radius="2" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1" />
|
||||
<feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1" />
|
||||
<feGaussianBlur stdDeviation="1.5" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" in="shadowBlurOuter1" />
|
||||
</filter>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="prefix__f">
|
||||
<feMorphology radius="1.08" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1" />
|
||||
<feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1" />
|
||||
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" in="shadowBlurOuter1" />
|
||||
</filter>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="prefix__h">
|
||||
<feMorphology radius="1.44" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1" />
|
||||
<feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1" />
|
||||
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" in="shadowBlurOuter1" />
|
||||
</filter>
|
||||
<path
|
||||
d="M18.528 23C16.887 23 7 38.241 7 44.803c0 5.174 2.987 10.572 11.528 10.572 7.82 0 11.528-5.346 11.528-10.572C30.056 38.158 20.169 23 18.528 23z"
|
||||
id="prefix__a" />
|
||||
<path
|
||||
d="M6.125 5C5.253 5 0 13.238 0 16.785 0 19.582 1.587 22.5 6.125 22.5c4.155 0 6.125-2.89 6.125-5.715C12.25 13.193 6.997 5 6.125 5z"
|
||||
id="prefix__b" />
|
||||
<path
|
||||
d="M31.313 0C30.128 0 23 11.122 23 15.91c0 3.776 2.154 7.715 8.313 7.715 5.64 0 8.312-3.901 8.312-7.715 0-4.849-7.129-15.91-8.313-15.91z"
|
||||
id="prefix__c" />
|
||||
<mask id="prefix__e" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-2" y="-2"
|
||||
width="27.056" height="36.375">
|
||||
<path fill="#fff" d="M5 21h27.056v36.375H5z" />
|
||||
<use xlink:href="#prefix__a" />
|
||||
</mask>
|
||||
<mask id="prefix__g" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-1.08" y="-1.08"
|
||||
width="14.41" height="19.66">
|
||||
<path fill="#fff" d="M-1.08 3.92h14.41v19.66H-1.08z" />
|
||||
<use xlink:href="#prefix__b" />
|
||||
</mask>
|
||||
<mask id="prefix__i" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-1.44" y="-1.44"
|
||||
width="19.505" height="26.505">
|
||||
<path fill="#fff" d="M21.56-1.44h19.505v26.505H21.56z" />
|
||||
<use xlink:href="#prefix__c" />
|
||||
</mask>
|
||||
</defs>
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<g transform="translate(3 2)">
|
||||
<use fill="#000" filter="url(#prefix__d)" xlink:href="#prefix__a" />
|
||||
<use fill-opacity=".3" fill="#55A4FF" xlink:href="#prefix__a" />
|
||||
<use stroke="#FFF" mask="url(#prefix__e)" stroke-width="4" xlink:href="#prefix__a" />
|
||||
</g>
|
||||
<g transform="translate(3 2)">
|
||||
<use fill="#000" filter="url(#prefix__f)" xlink:href="#prefix__b" />
|
||||
<use fill="#55A4FF" xlink:href="#prefix__b" />
|
||||
<use stroke="#FFF" mask="url(#prefix__g)" stroke-width="2.16" xlink:href="#prefix__b" />
|
||||
</g>
|
||||
<g transform="translate(3 2)">
|
||||
<use fill="#000" filter="url(#prefix__h)" xlink:href="#prefix__c" />
|
||||
<use fill="#55A4FF" xlink:href="#prefix__c" />
|
||||
<use stroke="#FFF" mask="url(#prefix__i)" stroke-width="2.88" xlink:href="#prefix__c" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.3 KiB |
@ -0,0 +1,66 @@
|
||||
<svg width="46" height="63" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="prefix__d">
|
||||
<feMorphology radius="2" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1" />
|
||||
<feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1" />
|
||||
<feGaussianBlur stdDeviation="1.5" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" in="shadowBlurOuter1" />
|
||||
</filter>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="prefix__f">
|
||||
<feMorphology radius="1.08" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1" />
|
||||
<feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1" />
|
||||
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" in="shadowBlurOuter1" />
|
||||
</filter>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="prefix__h">
|
||||
<feMorphology radius="1.44" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1" />
|
||||
<feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1" />
|
||||
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" in="shadowBlurOuter1" />
|
||||
</filter>
|
||||
<path
|
||||
d="M18.528 23C16.887 23 7 38.241 7 44.803c0 5.174 2.987 10.572 11.528 10.572 7.82 0 11.528-5.346 11.528-10.572C30.056 38.158 20.169 23 18.528 23z"
|
||||
id="prefix__a" />
|
||||
<path
|
||||
d="M6.125 5C5.253 5 0 13.238 0 16.785 0 19.582 1.587 22.5 6.125 22.5c4.155 0 6.125-2.89 6.125-5.715C12.25 13.193 6.997 5 6.125 5z"
|
||||
id="prefix__b" />
|
||||
<path
|
||||
d="M31.313 0C30.128 0 23 11.122 23 15.91c0 3.776 2.154 7.715 8.313 7.715 5.64 0 8.312-3.901 8.312-7.715 0-4.849-7.129-15.91-8.313-15.91z"
|
||||
id="prefix__c" />
|
||||
<mask id="prefix__e" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-2" y="-2"
|
||||
width="27.056" height="36.375">
|
||||
<path fill="#fff" d="M5 21h27.056v36.375H5z" />
|
||||
<use xlink:href="#prefix__a" />
|
||||
</mask>
|
||||
<mask id="prefix__g" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-1.08" y="-1.08"
|
||||
width="14.41" height="19.66">
|
||||
<path fill="#fff" d="M-1.08 3.92h14.41v19.66H-1.08z" />
|
||||
<use xlink:href="#prefix__b" />
|
||||
</mask>
|
||||
<mask id="prefix__i" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-1.44" y="-1.44"
|
||||
width="19.505" height="26.505">
|
||||
<path fill="#fff" d="M21.56-1.44h19.505v26.505H21.56z" />
|
||||
<use xlink:href="#prefix__c" />
|
||||
</mask>
|
||||
</defs>
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<g transform="translate(3 2)">
|
||||
<use fill="#000" filter="url(#prefix__d)" xlink:href="#prefix__a" />
|
||||
<use fill="#55A4FF" xlink:href="#prefix__a" />
|
||||
<use stroke="#FFF" mask="url(#prefix__e)" stroke-width="4" xlink:href="#prefix__a" />
|
||||
</g>
|
||||
<g transform="translate(3 2)">
|
||||
<use fill="#000" filter="url(#prefix__f)" xlink:href="#prefix__b" />
|
||||
<use fill="#55A4FF" xlink:href="#prefix__b" />
|
||||
<use stroke="#FFF" mask="url(#prefix__g)" stroke-width="2.16" xlink:href="#prefix__b" />
|
||||
</g>
|
||||
<g transform="translate(3 2)">
|
||||
<use fill="#000" filter="url(#prefix__h)" xlink:href="#prefix__c" />
|
||||
<use fill="#55A4FF" xlink:href="#prefix__c" />
|
||||
<use stroke="#FFF" mask="url(#prefix__i)" stroke-width="2.88" xlink:href="#prefix__c" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.3 KiB |
@ -0,0 +1,67 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="55" height="63">
|
||||
<defs>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="prefix__e">
|
||||
<feMorphology radius="2" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1" />
|
||||
<feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1" />
|
||||
<feGaussianBlur stdDeviation="1.5" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" in="shadowBlurOuter1" />
|
||||
</filter>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="prefix__g">
|
||||
<feMorphology radius="1.08" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1" />
|
||||
<feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1" />
|
||||
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" in="shadowBlurOuter1" />
|
||||
</filter>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="prefix__i">
|
||||
<feMorphology radius="1.44" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1" />
|
||||
<feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1" />
|
||||
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" in="shadowBlurOuter1" />
|
||||
</filter>
|
||||
<path
|
||||
d="M22.528 23C20.887 23 11 38.241 11 44.803c0 5.174 2.987 10.572 11.528 10.572 7.82 0 11.528-5.346 11.528-10.572C34.056 38.158 24.169 23 22.528 23z"
|
||||
id="prefix__a" />
|
||||
<path
|
||||
d="M10.125 5C9.253 5 4 13.238 4 16.785c0 2.797 1.587 5.715 6.125 5.715 4.155 0 6.125-2.89 6.125-5.715C16.25 13.193 10.997 5 10.125 5z"
|
||||
id="prefix__b" />
|
||||
<path
|
||||
d="M35.313 0C34.129 0 27 11.122 27 15.91c0 3.776 2.154 7.715 8.313 7.715 5.64 0 8.312-3.901 8.312-7.715 0-4.849-7.129-15.91-8.313-15.91z"
|
||||
id="prefix__c" />
|
||||
<mask id="prefix__f" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-2" y="-2" width="27.056"
|
||||
height="36.375">
|
||||
<path fill="#fff" d="M9 21h27.056v36.375H9z" />
|
||||
<use xlink:href="#prefix__a" />
|
||||
</mask>
|
||||
<mask id="prefix__h" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-1.08" y="-1.08"
|
||||
width="14.41" height="19.66">
|
||||
<path fill="#fff" d="M2.92 3.92h14.41v19.66H2.92z" />
|
||||
<use xlink:href="#prefix__b" />
|
||||
</mask>
|
||||
<mask id="prefix__j" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-1.44" y="-1.44"
|
||||
width="19.505" height="26.505">
|
||||
<path fill="#fff" d="M25.56-1.44h19.505v26.505H25.56z" />
|
||||
<use xlink:href="#prefix__c" />
|
||||
</mask>
|
||||
<rect id="prefix__d" x="-8.105" y="28.395" width="67" height="4" rx="2" />
|
||||
</defs>
|
||||
<g transform="translate(2 2)" fill="none" fill-rule="evenodd">
|
||||
<use height="100%" width="100%" xlink:href="#prefix__a" fill="#000" filter="url(#prefix__e)" />
|
||||
<use height="100%" width="100%" xlink:href="#prefix__a" fill="#55a4ff" fill-opacity=".3" />
|
||||
<use height="100%" width="100%" xlink:href="#prefix__a" mask="url(#prefix__f)" stroke="#fff" stroke-width="4" />
|
||||
</g>
|
||||
<g transform="translate(2 2)" fill="none" fill-rule="evenodd">
|
||||
<use height="100%" width="100%" xlink:href="#prefix__b" fill="#000" filter="url(#prefix__g)" />
|
||||
<use height="100%" width="100%" xlink:href="#prefix__b" fill="#55a4ff" fill-opacity=".3" />
|
||||
<use height="100%" width="100%" xlink:href="#prefix__b" mask="url(#prefix__h)" stroke="#fff"
|
||||
stroke-width="2.16" />
|
||||
</g>
|
||||
<g transform="translate(2 2)" fill="none" fill-rule="evenodd">
|
||||
<use height="100%" width="100%" xlink:href="#prefix__c" fill="#000" filter="url(#prefix__i)" />
|
||||
<use height="100%" width="100%" xlink:href="#prefix__c" fill="#55a4ff" fill-opacity=".3" />
|
||||
<use height="100%" width="100%" xlink:href="#prefix__c" mask="url(#prefix__j)" stroke="#fff"
|
||||
stroke-width="2.88" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.5 KiB |
@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="600" width="600" data-name="Calque 1">
|
||||
<path fill="#005892" d="M0 0h600v600H0z" />
|
||||
<rect x="220.481" y="111.57" width="159.038" height="159.038" rx="12.759" ry="12.759" fill="#fff" />
|
||||
<path fill="#005891" d="M334.557 134.05l17.013 17.697-24.152 6.152z" />
|
||||
<path
|
||||
d="M357.95 191.089a57.646 57.646 0 00-10.178-32.81l-5.164 1.974a56.05 56.05 0 0110.253 30.836 53.165 53.165 0 01-45.57 52.329 210.152 210.152 0 01-1.747-104.81 55.443 55.443 0 0119.747 6l1.291-4.861a57.57 57.57 0 00-19.747-6.152 150.684 150.684 0 018.127-22.025h-7.595a164.05 164.05 0 00-7.595 21.645 57.95 57.95 0 000 115.823h1.975c1.975 7.063 4.253 14.278 7.063 21.646h7.063c-2.886-7.595-5.392-15.19-7.595-22.254a57.95 57.95 0 0049.671-57.341z"
|
||||
fill="#005891" />
|
||||
<path d="M298.633 130.405h-7.063" fill="#fff" />
|
||||
<g fill="#fff">
|
||||
<path
|
||||
d="M123.418 315.342h22.025l14.582 44.126 14.05-44.126h22.102l7.975 76.48H182.05l-3.266-38.278-11.317 38.279h-15.873l-11.317-38.279-4.48 38.279H114zM268.405 372.608h-34.709v-10.254h26.279V346.33H233.24v-11.544h35.164v-19.443h-56.278v76.48h56.278zM403.975 372.608H369.19v-10.254h26.278V346.33h-26.734v-11.544h35.24v-19.443H347.62v76.48h56.355zM297.038 391.823h21.19v-57.038h18.76v-19.443h-59.165v19.443h19.215zM448.101 314.658a37.975 37.975 0 1037.975 37.975 37.975 37.975 0 00-37.975-37.975zm0 57.494a19.443 19.443 0 1119.443-19.443 19.443 19.443 0 01-19.443 19.443zM134.962 464.127h23.696v-14.81h-23.696v-14.963h30.684v-18.607H114v72.607h20.962zM213.57 458.81s10.936-1.215 10.936-21.19a19.519 19.519 0 00-18.835-21.873h-34.86v72.607h17.695V461.62h6.532l11.165 26.734h20.886zm-11.848-11.544h-13.52v-17.469h13.52a9.494 9.494 0 010 17.469zM274.025 415.747h-16.253l-27.418 72.607h20.735l5.392-13.519h19.975l4.557 13.52h19.822zm-15.19 45.114l6.988-19.52 6.987 19.52zM321.494 449.316l26.05 39.038h16.785v-72.607h-18.911v42.456l-24.152-42.456h-18.38v72.607h18.608zM418.253 465.038a18.38 18.38 0 11-.987-26.43l11.848-13.292a36.076 36.076 0 100 53.773zM486 470.127h-33.038v-9.722h24.987V445.14h-25.443v-10.936H486V415.67h-53.544v72.76H486z" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg enable-background="new 0 0 64 64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
|
||||
<ellipse style="stroke-width: 0px; stroke: rgb(0, 0, 0); fill:#3d3c3c;" cx="32" cy="32" rx="30" ry="30" />
|
||||
<path
|
||||
d="m32 2.5c.98 0 1.76.79 1.76 1.76v8.25l2.82-4.09c.35-.5.9-.77 1.47-.76.34 0 .68.11.98.31.8.55 1.01 1.65.45 2.45l-5.73 8.31v3.56 6.66l8.85-5.11 4.33-9.11c.42-.88 1.47-1.25 2.35-.84.33.16.59.4.76.7.29.49.33 1.1.07 1.65l-2.13 4.49 7.15-4.13c.85-.49 1.92-.2 2.41.65.49.85.2 1.92-.65 2.41l-7.15 4.13 4.96.4c.61.05 1.12.4 1.4.89.17.3.25.64.22 1.01-.08.97-.92 1.69-1.9 1.62l-10.06-.8-8.84 5.09 5.77 3.33 3.08 1.78 10.06-.8c.97-.08 1.82.64 1.9 1.62.03.36-.05.71-.22 1.01-.28.49-.79.84-1.4.89l-4.96.4 7.15 4.13c.85.49 1.13 1.56.65 2.41-.49.85-1.56 1.13-2.41.64l-7.15-4.13 2.13 4.49c.26.55.22 1.17-.07 1.65-.17.29-.43.54-.76.69-.88.42-1.93.05-2.35-.83l-4.33-9.11-8.85-5.11v6.66 3.56l5.73 8.31c.55.8.35 1.9-.45 2.45-.3.21-.64.31-.98.31-.57.01-1.12-.26-1.47-.76l-2.82-4.09v8.25c0 .98-.79 1.76-1.76 1.76-.98 0-1.76-.79-1.76-1.76v-8.25l-2.82 4.09c-.35.5-.9.77-1.47.76-.34 0-.68-.11-.98-.31-.8-.55-1.01-1.65-.45-2.45l5.73-8.31v-3.56-6.66l-5.77 3.33-3.08 1.78-4.33 9.11c-.42.88-1.47 1.25-2.35.83-.33-.16-.59-.4-.76-.69-.29-.49-.33-1.1-.07-1.65l2.14-4.49-7.15 4.13c-.85.49-1.92.2-2.41-.64-.49-.85-.2-1.92.64-2.41l7.15-4.13-4.96-.4c-.61-.05-1.12-.4-1.4-.89-.17-.3-.25-.64-.22-1.01.08-.97.92-1.69 1.9-1.62l10.06.8 3.08-1.78 5.75-3.33-8.85-5.11-10.06.8c-.97.08-1.82-.64-1.9-1.62-.03-.36.05-.71.22-1.01.28-.49.79-.84 1.4-.89l4.96-.4-7.15-4.11c-.85-.49-1.13-1.56-.64-2.41.49-.85 1.56-1.13 2.41-.65l7.15 4.13-2.14-4.49c-.26-.55-.22-1.17.07-1.65.17-.29.43-.54.76-.7.88-.42 1.93-.05 2.35.84l4.33 9.11 8.85 5.11v-6.66-3.56l-5.73-8.31c-.55-.8-.35-1.9.45-2.45.3-.21.64-.31.98-.31.57-.01 1.12.26 1.47.76l2.82 4.09v-8.25c.01-.97.79-1.76 1.77-1.76"
|
||||
fill="#dae1e4" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg enable-background="new 0 0 64 64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
|
||||
<ellipse style="stroke-width: 0px; stroke: rgb(0, 0, 0); fill:#3d3c3c;" cx="32" cy="32" rx="30" ry="30"/>
|
||||
<g transform="matrix(0.109429, 0, 0, 0.095795, 3.683853, 5.87504)" style="">
|
||||
<polygon style="fill:#FFDA44;" points="225.584 244.867 174.304 380.884 268.543 380.884 209.837 509.421 367.316 333.616 271.782 333.616 303.985 244.867"/>
|
||||
<polygon style="fill:#CCA400;" points="304.519 244.867 226.118 244.867 207.482 294.3 286.581 294.3"/>
|
||||
<path style="fill:#B8D6FD;" d="M 459.559 266.555 C 488.522 266.555 512.001 243.077 512.001 214.113 C 512.001 185.149 488.523 161.671 459.559 161.671 C 450.829 161.671 442.605 163.816 435.364 167.589 C 428.157 153.316 416.099 141.917 401.341 135.574 C 401.341 135.443 401.351 135.316 401.351 135.185 C 401.351 62.632 342.535 3.817 269.982 3.817 C 209.899 3.817 159.273 44.169 143.634 99.239 C 109.041 105.309 81.724 132.452 75.398 166.956 C 68.464 163.574 60.675 161.671 52.44 161.671 C 23.479 161.672 0 185.15 0 214.114 C 0 243.078 23.479 266.556 52.442 266.556 L 459.559 266.556 L 459.559 266.555 Z"/>
|
||||
<path style="opacity:0.41;fill:#6AB3EA;enable-background:new ;" d="M 458.404 160.434 C 449.674 160.434 441.45 162.579 434.209 166.352 C 427.002 152.079 414.944 140.68 400.186 134.337 C 400.186 134.206 400.196 134.079 400.196 133.948 C 400.196 61.395 341.38 2.58 268.827 2.58 C 257.171 2.58 245.875 4.105 235.117 6.955 C 291.333 21.84 332.772 73.052 332.772 133.95 C 332.772 134.081 332.763 134.208 332.762 134.339 C 347.519 140.681 359.578 152.081 366.785 166.354 C 374.026 162.58 382.25 160.436 390.98 160.436 C 419.943 160.436 443.422 183.914 443.422 212.878 C 443.422 241.841 419.944 265.32 390.98 265.32 L 458.404 265.32 C 487.367 265.32 510.846 241.841 510.846 212.878 C 510.846 183.912 487.367 160.434 458.404 160.434 Z"/>
|
||||
<g style="opacity:0.41;">
|
||||
<path style="fill:#6AB3EA;" d="M258.252,34.812c0,3.364-2.216,6.456-5.612,7.421c-40.109,11.389-68.121,48.482-68.121,90.201 c0,4.264-3.455,7.718-7.718,7.718s-7.718-3.455-7.718-7.718c0-48.587,32.626-91.785,79.341-105.052 c4.1-1.165,8.369,1.216,9.534,5.316C258.157,33.404,258.252,34.114,258.252,34.812z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg enable-background="new 0 0 64 64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
|
||||
<ellipse style="stroke-width: 0px; stroke: rgb(0, 0, 0); fill:#3d3c3c;" cx="32" cy="32" rx="30" ry="30"/>
|
||||
<path fill="#F8EFE0" d="M 11.018 52.475 L 11.018 31.819 C 7.317 33.065 4.779 29.687 7.284 26.959 C 7.325 26.916 7.371 26.873 7.425 26.837 L 30.938 10.768 C 31.242 10.522 31.712 10.497 32.05 10.727 L 55.617 26.768 C 55.654 26.793 55.688 26.819 55.72 26.851 C 56.812 27.879 57.084 29.019 56.82 29.983 C 56.692 30.449 56.434 30.88 56.071 31.238 C 55.708 31.596 55.249 31.867 54.735 32.029 C 53.911 32.288 52.931 32.281 51.937 31.869 L 51.937 51.358 C 43.944 54.785 42.3 46.755 42.28 46.918 C 41.461 53.613 28.847 53.227 26.809 48.767 C 26.439 47.958 26.67 47.804 26.141 47.766 C 23.045 47.544 22.868 55.347 11.018 52.475 Z M 51.987 12.422 L 51.987 20.469 L 44.911 16.382 L 44.911 12.422 L 51.987 12.422 Z" style=""/>
|
||||
<path fill="#D93133" d="M 11.018 31.819 C 10.054 32.144 9.151 32.151 8.401 31.927 C 7.816 31.754 7.322 31.444 6.959 31.043 C 6.596 30.643 6.366 30.156 6.295 29.618 C 6.188 28.785 6.472 27.843 7.284 26.959 C 7.325 26.916 7.371 26.873 7.425 26.837 L 30.938 10.768 C 31.242 10.522 31.712 10.497 32.05 10.727 L 55.617 26.768 C 55.654 26.793 55.688 26.819 55.72 26.851 C 56.812 27.879 57.084 29.019 56.82 29.983 C 56.692 30.449 56.434 30.88 56.071 31.238 C 55.708 31.596 55.249 31.867 54.735 32.029 C 53.911 32.288 52.931 32.281 51.937 31.869 L 49.63 30.982 C 49.63 30.618 33.464 19.43 31.679 18.213 C 29.788 19.473 13.326 30.571 13.326 31.04 L 11.018 31.819 Z M 51.987 12.422 L 51.987 20.469 L 44.911 16.382 L 44.911 12.422 L 51.987 12.422 Z" style=""/>
|
||||
<path fill="#313A58" d="M 31.595 25.496 C 33.228 25.496 34.711 26.081 35.784 27.021 C 36.861 27.963 37.526 29.076 37.526 30.503 L 37.526 35.325 L 25.662 35.325 L 25.662 30.503 C 25.662 29.073 26.33 27.961 27.404 27.021 C 28.479 26.081 29.963 25.496 31.595 25.496 Z" style=""/>
|
||||
<path fill="#ABB9BC" d="M 32.111 31.421 L 32.111 34.426 L 36.496 34.426 L 36.496 31.421 L 32.111 31.421 Z M 32.111 26.424 L 32.111 30.517 L 36.496 30.517 L 36.496 30.505 C 36.496 29.326 35.945 28.439 35.056 27.661 C 34.282 26.983 33.252 26.529 32.111 26.424 Z M 31.079 30.517 L 31.079 26.424 C 29.936 26.531 28.909 26.983 28.134 27.661 C 27.245 28.439 26.694 29.326 26.694 30.505 L 26.694 30.517 L 31.079 30.517 Z M 31.079 34.423 L 31.079 31.421 L 26.694 31.421 L 26.694 34.426 L 31.079 34.426 L 31.079 34.423 Z" style=""/>
|
||||
<path fill="#313A58" d="M 51.92 31.732 L 49.64 30.959 L 49.64 52.389 L 51.92 52.389 L 51.92 31.732 Z M 10.908 31.819 L 13.189 31.046 L 13.189 52.476 L 10.908 52.476 L 10.908 31.819 Z" style=""/>
|
||||
<path d="M 11.097 51.603 C 13.269 52.586 15.988 52.276 18.451 51.315 C 21.367 50.176 23.866 48.168 24.668 46.318 C 24.9 45.781 25.509 45.54 26.029 45.779 C 26.259 45.885 26.444 46.075 26.547 46.312 C 27.432 48.152 28.886 49.487 30.554 50.246 C 31.623 50.733 32.775 50.983 33.918 50.978 C 35.051 50.973 36.18 50.717 37.211 50.195 C 38.688 49.446 39.974 48.13 40.802 46.195 C 41.031 45.656 41.641 45.412 42.163 45.649 C 42.416 45.764 42.614 45.978 42.711 46.245 C 43.106 47.121 43.54 47.869 44.009 48.496 C 45.11 49.969 46.402 50.756 47.805 50.981 C 49.259 51.215 50.874 50.868 52.56 50.07 C 53.763 49.501 55 48.701 56.239 47.714 L 57.499 49.397 C 56.142 50.478 54.77 51.363 53.416 52.004 C 51.373 52.971 49.365 53.383 47.49 53.082 C 45.567 52.773 43.824 51.731 42.377 49.796 C 42.148 49.488 41.933 49.17 41.734 48.842 C 40.756 50.32 39.505 51.399 38.116 52.103 C 36.799 52.772 35.361 53.098 33.918 53.104 C 32.484 53.109 31.046 52.799 29.722 52.197 C 28.122 51.468 26.677 50.311 25.588 48.764 C 24.183 50.57 21.811 52.279 19.178 53.307 C 16.265 54.444 12.989 54.782 10.273 53.553 L 11.097 51.603 Z" style="fill: rgb(30, 130, 255);"/>
|
||||
<path d="M 8.218 34.7 C 8.218 34.7 8.173 34.7 8.13 34.7 C 8.041 34.7 7.997 34.7 7.953 34.64 L 7.908 34.64 C 6.888 34.399 6.046 33.017 5.958 31.515 L 5.958 31.034 C 6.003 30.794 6.046 30.494 6.091 30.192 C 6.18 30.013 6.268 29.772 6.357 29.532 L 6.667 28.93 C 7.376 27.789 7.953 26.648 8.351 25.445 C 8.794 26.888 9.504 28.15 10.08 29.111 C 10.124 29.231 10.213 29.411 10.346 29.592 C 10.434 29.832 10.567 30.133 10.701 30.373 C 10.745 30.553 10.789 30.854 10.834 31.094 L 10.834 31.455 C 10.834 31.515 10.834 31.575 10.834 31.635 C 10.834 31.635 10.834 31.695 10.834 31.695 L 10.834 31.756 L 10.834 31.815 C 10.701 33.138 9.903 34.399 8.928 34.64 L 8.883 34.64 C 8.839 34.64 8.794 34.7 8.706 34.7 C 8.661 34.7 8.618 34.7 8.618 34.7 L 8.218 34.7" fill="#1e82ff" style=""/>
|
||||
<path d="M 17.152 21.924 C 17.152 21.924 17.107 21.924 17.064 21.924 C 16.975 21.924 16.931 21.924 16.887 21.864 L 16.842 21.864 C 15.822 21.623 14.98 20.241 14.892 18.739 L 14.892 18.258 C 14.937 18.018 14.98 17.718 15.025 17.416 C 15.114 17.237 15.202 16.996 15.291 16.756 L 15.601 16.154 C 16.31 15.013 16.887 13.872 17.285 12.669 C 17.728 14.112 18.438 15.374 19.014 16.335 C 19.058 16.455 19.147 16.635 19.28 16.816 C 19.368 17.056 19.501 17.357 19.635 17.597 C 19.679 17.777 19.723 18.078 19.768 18.318 L 19.768 18.679 C 19.768 18.739 19.768 18.799 19.768 18.859 C 19.768 18.859 19.768 18.919 19.768 18.919 L 19.768 18.98 L 19.768 19.039 C 19.635 20.362 18.837 21.623 17.862 21.864 L 17.817 21.864 C 17.773 21.864 17.728 21.924 17.64 21.924 C 17.595 21.924 17.552 21.924 17.552 21.924 L 17.152 21.924" fill="#1e82ff" style=""/>
|
||||
<path d="M 42.51 27.949 C 42.51 27.949 42.465 27.949 42.422 27.949 C 42.333 27.949 42.289 27.949 42.245 27.889 L 42.2 27.889 C 41.18 27.648 40.338 26.266 40.25 24.764 L 40.25 24.283 C 40.295 24.043 40.338 23.743 40.383 23.441 C 40.472 23.262 40.56 23.021 40.649 22.781 L 40.959 22.179 C 41.668 21.038 42.245 19.897 42.643 18.694 C 43.086 20.137 43.796 21.399 44.372 22.36 C 44.416 22.48 44.505 22.66 44.638 22.841 C 44.726 23.081 44.859 23.382 44.993 23.622 C 45.037 23.802 45.081 24.103 45.126 24.343 L 45.126 24.704 C 45.126 24.764 45.126 24.824 45.126 24.884 C 45.126 24.884 45.126 24.944 45.126 24.944 L 45.126 25.005 L 45.126 25.064 C 44.993 26.387 44.195 27.648 43.22 27.889 L 43.175 27.889 C 43.131 27.889 43.086 27.949 42.998 27.949 C 42.953 27.949 42.91 27.949 42.91 27.949 L 42.51 27.949" fill="#1e82ff" style=""/>
|
||||
<path d="M 30.168 12.518 C 30.168 12.518 30.123 12.518 30.08 12.518 C 29.991 12.518 29.947 12.518 29.903 12.458 L 29.858 12.458 C 28.838 12.217 27.996 10.835 27.908 9.333 L 27.908 8.852 C 27.953 8.612 27.996 8.312 28.041 8.01 C 28.13 7.831 28.218 7.59 28.307 7.35 L 28.617 6.748 C 29.326 5.607 29.903 4.466 30.301 3.263 C 30.744 4.706 31.454 5.968 32.03 6.929 C 32.074 7.049 32.163 7.229 32.296 7.41 C 32.384 7.65 32.517 7.951 32.651 8.191 C 32.695 8.371 32.739 8.672 32.784 8.912 L 32.784 9.273 C 32.784 9.333 32.784 9.393 32.784 9.453 C 32.784 9.453 32.784 9.513 32.784 9.513 L 32.784 9.574 L 32.784 9.633 C 32.651 10.956 31.853 12.217 30.878 12.458 L 30.833 12.458 C 30.789 12.458 30.744 12.518 30.656 12.518 C 30.611 12.518 30.568 12.518 30.568 12.518 L 30.168 12.518" fill="#1e82ff" style=""/>
|
||||
<path d="M 54.328 36.78 C 54.328 36.78 54.283 36.78 54.24 36.78 C 54.151 36.78 54.107 36.78 54.063 36.72 L 54.018 36.72 C 52.998 36.479 52.156 35.097 52.068 33.595 L 52.068 33.114 C 52.113 32.874 52.156 32.574 52.201 32.272 C 52.29 32.093 52.378 31.852 52.467 31.612 L 52.777 31.01 C 53.486 29.869 54.063 28.728 54.461 27.525 C 54.904 28.968 55.614 30.23 56.19 31.191 C 56.234 31.311 56.323 31.491 56.456 31.672 C 56.544 31.912 56.677 32.213 56.811 32.453 C 56.855 32.633 56.899 32.934 56.944 33.174 L 56.944 33.535 C 56.944 33.595 56.944 33.655 56.944 33.715 C 56.944 33.715 56.944 33.775 56.944 33.775 L 56.944 33.836 L 56.944 33.895 C 56.811 35.218 56.013 36.479 55.038 36.72 L 54.993 36.72 C 54.949 36.72 54.904 36.78 54.816 36.78 C 54.771 36.78 54.728 36.78 54.728 36.78 L 54.328 36.78" fill="#1e82ff" style=""/>
|
||||
<path d="M 10.92 57.018 C 13.092 58.001 15.811 57.691 18.274 56.73 C 21.19 55.591 23.689 53.583 24.491 51.733 C 24.723 51.196 25.332 50.955 25.852 51.194 C 26.082 51.3 26.267 51.49 26.37 51.727 C 27.255 53.567 28.709 54.902 30.377 55.661 C 31.446 56.148 32.598 56.398 33.741 56.393 C 34.874 56.388 36.003 56.132 37.034 55.61 C 38.511 54.861 39.797 53.545 40.625 51.61 C 40.854 51.071 41.464 50.827 41.986 51.064 C 42.239 51.179 42.437 51.393 42.534 51.66 C 42.929 52.536 43.363 53.284 43.832 53.911 C 44.933 55.384 46.225 56.171 47.628 56.396 C 49.082 56.63 50.697 56.283 52.383 55.485 C 53.586 54.916 54.823 54.116 56.062 53.129 L 57.322 54.812 C 55.965 55.893 54.593 56.778 53.239 57.419 C 51.196 58.386 49.188 58.798 47.313 58.497 C 45.39 58.188 43.647 57.146 42.2 55.211 C 41.971 54.903 41.756 54.585 41.557 54.257 C 40.579 55.735 39.328 56.814 37.939 57.518 C 36.622 58.187 35.184 58.513 33.741 58.519 C 32.307 58.524 30.869 58.214 29.545 57.612 C 27.945 56.883 26.5 55.726 25.411 54.179 C 24.006 55.985 21.634 57.694 19.001 58.722 C 16.088 59.859 12.812 60.197 10.096 58.968 L 10.92 57.018 Z" style="fill: rgb(30, 130, 255);"/>
|
||||
</svg>
|
After Width: | Height: | Size: 8.8 KiB |
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg enable-background="new 0 0 64 64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
|
||||
<ellipse style="stroke-width: 0px; stroke: rgb(0, 0, 0); fill:#3d3c3c;" cx="32" cy="32" rx="30" ry="30"/>
|
||||
<path d="M 10.382 37.307 C 12.554 38.29 15.273 37.98 17.736 37.019 C 20.652 35.88 23.151 33.872 23.953 32.022 C 24.185 31.485 24.794 31.244 25.314 31.483 C 25.544 31.589 25.729 31.779 25.832 32.016 C 26.717 33.856 28.171 35.191 29.839 35.95 C 30.908 36.437 32.06 36.687 33.203 36.682 C 34.336 36.677 35.465 36.421 36.496 35.899 C 37.973 35.15 39.259 33.834 40.087 31.899 C 40.316 31.36 40.926 31.116 41.448 31.353 C 41.701 31.468 41.899 31.682 41.996 31.949 C 42.391 32.825 42.825 33.573 43.294 34.2 C 44.395 35.673 45.687 36.46 47.09 36.685 C 48.544 36.919 50.159 36.572 51.845 35.774 C 53.048 35.205 54.285 34.405 55.524 33.418 L 56.784 35.101 C 55.427 36.182 54.055 37.067 52.701 37.708 C 50.658 38.675 48.65 39.087 46.775 38.786 C 44.852 38.477 43.109 37.435 41.662 35.5 C 41.433 35.192 41.218 34.874 41.019 34.546 C 40.041 36.024 38.79 37.103 37.401 37.807 C 36.084 38.476 34.646 38.802 33.203 38.808 C 31.769 38.813 30.331 38.503 29.007 37.901 C 27.407 37.172 25.962 36.015 24.873 34.468 C 23.468 36.274 21.096 37.983 18.463 39.011 C 15.55 40.148 12.274 40.486 9.558 39.257 L 10.382 37.307 Z" style="fill: rgb(30, 130, 255);"/>
|
||||
<path d="M 10.205 42.722 C 12.377 43.705 15.096 43.395 17.559 42.434 C 20.475 41.295 22.974 39.287 23.776 37.437 C 24.008 36.9 24.617 36.659 25.137 36.898 C 25.367 37.004 25.552 37.194 25.655 37.431 C 26.54 39.271 27.994 40.606 29.662 41.365 C 30.731 41.852 31.883 42.102 33.026 42.097 C 34.159 42.092 35.288 41.836 36.319 41.314 C 37.796 40.565 39.082 39.249 39.91 37.314 C 40.139 36.775 40.749 36.531 41.271 36.768 C 41.524 36.883 41.722 37.097 41.819 37.364 C 42.214 38.24 42.648 38.988 43.117 39.615 C 44.218 41.088 45.51 41.875 46.913 42.1 C 48.367 42.334 49.982 41.987 51.668 41.189 C 52.871 40.62 54.108 39.82 55.347 38.833 L 56.607 40.516 C 55.25 41.597 53.878 42.482 52.524 43.123 C 50.481 44.09 48.473 44.502 46.598 44.201 C 44.675 43.892 42.932 42.85 41.485 40.915 C 41.256 40.607 41.041 40.289 40.842 39.961 C 39.864 41.439 38.613 42.518 37.224 43.222 C 35.907 43.891 34.469 44.217 33.026 44.223 C 31.592 44.228 30.154 43.918 28.83 43.316 C 27.23 42.587 25.785 41.43 24.696 39.883 C 23.291 41.689 20.919 43.398 18.286 44.426 C 15.373 45.563 12.097 45.901 9.381 44.672 L 10.205 42.722 Z" style="fill: rgb(30, 130, 255);"/>
|
||||
<path d="M 32.307 33.157 C 30.008 33.038 27.346 31.638 25.776 29.76 C 25.48 29.421 25.206 29.064 24.956 28.688 C 23.585 30.561 21.153 32.357 18.438 33.424 C 15.546 34.563 12.297 34.903 9.61 33.677 L 10.301 32.03 C 12.342 32.962 14.845 32.775 17.183 31.979 C 17.253 28.669 18.202 25.534 19.838 22.875 C 21.336 20.442 23.646 18.223 26.281 16.786 C 29.429 15.07 33.861 14.165 36.905 16.582 C 40.064 19.088 39.596 23.333 36.462 25.669 C 35.744 26.203 34.894 26.543 34.027 26.631 C 33.319 26.702 32.602 26.606 31.934 26.309 C 31.263 26.011 30.648 25.518 30.154 24.801 C 29.581 23.968 29.17 22.827 29.031 21.336 C 28.992 20.904 29.296 20.523 29.711 20.48 C 30.125 20.44 30.493 20.757 30.532 21.188 C 30.643 22.376 30.953 23.26 31.383 23.885 C 31.708 24.357 32.102 24.676 32.525 24.866 C 32.954 25.056 33.42 25.116 33.885 25.069 C 34.48 25.009 35.072 24.769 35.582 24.39 C 37.883 22.674 38.346 19.7 35.99 17.83 C 26.886 12.683 22.711 27.316 31.469 31.199 C 32.079 31.342 32.703 31.412 33.329 31.411 C 34.495 31.407 35.656 31.142 36.717 30.6 C 38.239 29.821 39.562 28.459 40.413 26.455 C 40.605 26 41.116 25.793 41.554 25.994 C 41.766 26.091 41.931 26.272 42.013 26.498 C 42.418 27.404 42.863 28.177 43.343 28.823 C 44.48 30.357 45.818 31.177 47.274 31.413 C 48.771 31.655 50.429 31.298 52.154 30.475 C 53.379 29.893 54.635 29.073 55.89 28.065 L 56.947 29.488 C 55.592 30.576 54.222 31.465 52.872 32.109 C 50.847 33.075 48.86 33.487 47.01 33.188 C 45.117 32.881 43.402 31.847 41.976 29.924 C 41.694 29.542 41.434 29.145 41.197 28.733 C 40.211 30.324 38.919 31.474 37.476 32.212 C 36.175 32.876 34.753 33.201 33.329 33.207 C 32.988 33.209 32.647 33.192 32.307 33.157 Z" style="fill: rgb(30, 130, 255);"/>
|
||||
</svg>
|
After Width: | Height: | Size: 4.1 KiB |
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg enable-background="new 0 0 64 64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
|
||||
<ellipse style="stroke-width: 0px; stroke: rgb(0, 0, 0); fill:#3d3c3c;" cx="32" cy="32" rx="30" ry="30" />
|
||||
<path
|
||||
d="m61.55 22.14c-3.06-.84-7.3-2.16-9.33-3.51-3.39-2.25-4.77-2.26-7.12-3.02-2.35-.76-4.78-2.08-4.78-2.08s-2.57-2.17-6.5-2.77c-3.92-.6-5.65-2.61-5.65-2.61s-.6-1.38-2.2-1.96c-2.54-1.01-6.25 2.29-8.28 7.38-2.03 5.09-1.61 10.04.94 11.05 0 0 6.32 2.52 10.66 2.08 4.34-.44 7.8.39 7.8.39s3.64.85 7.37.58c3.72-.27 6.09.62 6.09.62s2.41.67 10.18.27c.31-.43.57-.91.77-1.43.67-1.69.64-3.47.05-4.99z"
|
||||
fill="#db5336" stroke="#db5336" stroke-miterlimit="10" />
|
||||
<ellipse transform="matrix(-.929-.37.37-.929 37.3113 37.9507)" cx="22.3" cy="15.4" rx="4.96" ry="9.92"
|
||||
fill="#ca2a14" />
|
||||
<g fill="#fff">
|
||||
<path
|
||||
d="m61.55 22.14c-1.77-.48-3.92-1.13-5.82-1.84.77 1.74.88 3.69.16 5.5-.46 1.15-1.2 2.1-2.12 2.84 1.58.07 3.84.09 6.97-.07.31-.43.57-.91.77-1.43.66-1.7.63-3.48.04-5" />
|
||||
<path
|
||||
d="m50.1 17.36c-1.98-1.03-3.21-1.17-5-1.75-.5-.16-1.01-.35-1.49-.54 1.27 2.47 1.49 5.53.35 8.41-.67 1.68-1.73 3.09-3.01 4.15 1.08.08 2.29.12 3.51.03 1.07-.08 2.02-.06 2.84.01 1.21-.93 2.19-2.2 2.8-3.73.89-2.21.82-4.56 0-6.58" />
|
||||
<path
|
||||
d="m37.81 12c-1.06-.5-2.42-1-3.99-1.24-.84-.13-1.57-.32-2.22-.54 1.6 2.52 1.73 6.77.05 10.99-.89 2.24-2.16 4.14-3.59 5.53.42 0 .83-.01 1.23-.05 1.8-.18 3.45-.15 4.76-.04 1.75-1.09 3.32-2.98 4.29-5.4 1.4-3.53 1.1-7.14-.53-9.25" />
|
||||
<path
|
||||
d="m24.53 15.02c-1.09 2.73-1.32 5.44-.8 7.43 1.21-1.31 2.34-3.11 3.18-5.22 1.08-2.72 1.47-5.4 1.2-7.46-1.4 1.19-2.7 3.02-3.58 5.25" />
|
||||
</g>
|
||||
<g fill="none" stroke="#1a171b" stroke-miterlimit="10">
|
||||
<path d="m13.55 10.5 4.7 2.19" />
|
||||
<path d="m13.55 10.5 13.28-3.87" />
|
||||
<path d="m13.55 10.5 8.74 13.45" />
|
||||
<path d="M 13.55,10.5 7,9" />
|
||||
</g>
|
||||
<path d="M4.5,59.5V9c0-1.38,1.12-2.5,2.5-2.5S9.5,7.62,9.5,9c0,1.21-0.86,2.22-2,2.45V59.5H4.5z" fill="#8b96ac" />
|
||||
<path
|
||||
d="m7 7c1.1 0 2 0.9 2 2s-0.9 2-2 2v48h-2v-50c0-1.1 0.9-2 2-2m0-1c-1.65 0-3 1.35-3 3v51h4v-48.17c1.16-0.41 2-1.52 2-2.83 0-1.65-1.35-3-3-3z"
|
||||
fill="#676b72" />
|
||||
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
@ -246,8 +246,8 @@
|
||||
<module>org.openhab.binding.mecmeter</module>
|
||||
<module>org.openhab.binding.melcloud</module>
|
||||
<module>org.openhab.binding.mercedesme</module>
|
||||
<module>org.openhab.binding.meteoalerte</module>
|
||||
<module>org.openhab.binding.meteoblue</module>
|
||||
<module>org.openhab.binding.meteofrance</module>
|
||||
<module>org.openhab.binding.meteostick</module>
|
||||
<module>org.openhab.binding.mffan</module>
|
||||
<module>org.openhab.binding.miele</module>
|
||||
|