Skip to content

Commit

Permalink
Implement ShellyPlus1PM (#2571)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sn0w3y authored Jun 19, 2024
1 parent ce7f4cf commit 514d5d4
Show file tree
Hide file tree
Showing 7 changed files with 654 additions and 2 deletions.
3 changes: 2 additions & 1 deletion io.openems.edge.io.shelly/readme.adoc
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
= Shelly WiFi Relay Switch

This bundle implements Shelly WiFi Relay Switches.
This bundle implements Shelly WiFi Relay Switches and Meters.

Compatible with
- https://www.shelly.com/de/products/shop/1xs25[Shelly 2.5]
- https://www.shelly.com/en/products/shop/shelly-3-em[Shelly 3EM]
- Shelly Plug S
- https://www.shelly.com/de/products/shop/shelly-plus-plug-s-1[Shelly Plus Plug S]
- https://www.shelly.com/de/products/shop/shelly-pro-3-em-120-a-1[Shelly Pro 3EM 3-Phase Meter]
- https://www.shelly.com/de/products/shop/shelly-plus-1-pm[Shelly Plus 1PM]

https://github.com/OpenEMS/openems/tree/develop/io.openems.edge.io.shelly[Source Code icon:github[]]
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.openems.edge.io.shelly.shellyplus1pm;

import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;

import io.openems.edge.meter.api.MeterType;
import io.openems.edge.meter.api.SinglePhase;

@ObjectClassDefinition(//
name = "IO Shelly Plus 1PM", //
description = "Implements the Shelly 2ndGen / Plug WiFi Switch.")
@interface Config {

@AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component")
String id() default "io0";

@AttributeDefinition(name = "Alias", description = "Human-readable name of this Component; defaults to Component-ID")
String alias() default "";

@AttributeDefinition(name = "Is enabled?", description = "Is this Component enabled?")
boolean enabled() default true;

@AttributeDefinition(name = "Phase", description = "Which Phase is this Shelly Plug connected to?")
SinglePhase phase() default SinglePhase.L1;

@AttributeDefinition(name = "IP-Address", description = "The IP address of the Shelly device.")
String ip();

@AttributeDefinition(name = "Meter-Type", description = "What is measured by this Meter?")
MeterType type() default MeterType.CONSUMPTION_METERED;

String webconsole_configurationFactory_nameHint() default "IO Shelly Plus 1PM [{id}]";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package io.openems.edge.io.shelly.shellyplus1pm;

import org.osgi.service.event.EventHandler;

import io.openems.common.channel.AccessMode;
import io.openems.common.channel.Level;
import io.openems.common.exceptions.OpenemsError.OpenemsNamedException;
import io.openems.common.types.OpenemsType;
import io.openems.edge.common.channel.BooleanDoc;
import io.openems.edge.common.channel.BooleanWriteChannel;
import io.openems.edge.common.channel.Doc;
import io.openems.edge.common.channel.StateChannel;
import io.openems.edge.common.channel.value.Value;
import io.openems.edge.common.component.OpenemsComponent;
import io.openems.edge.io.api.DigitalOutput;
import io.openems.edge.meter.api.ElectricityMeter;
import io.openems.edge.meter.api.SinglePhaseMeter;

public interface IoShellyPlus1Pm
extends DigitalOutput, SinglePhaseMeter, ElectricityMeter, OpenemsComponent, EventHandler {

public static enum ChannelId implements io.openems.edge.common.channel.ChannelId {
/**
* Holds writes to Relay Output for debugging.
*
* <ul>
* <li>Interface: ShellyPlus1PM
* <li>Type: Boolean
* <li>Range: On/Off
* </ul>
*/
DEBUG_RELAY(Doc.of(OpenemsType.BOOLEAN)), //
/**
* Relay Output.
*
* <ul>
* <li>Interface: ShellyPlus1PM
* <li>Type: Boolean
* <li>Range: On/Off
* </ul>
*/
RELAY(new BooleanDoc() //
.accessMode(AccessMode.READ_WRITE) //
.onChannelSetNextWriteMirrorToDebugChannel(ChannelId.DEBUG_RELAY)),
/**
* Indicates whether the Shelly needs a restart.
*
* <ul>
* <li>Interface: ShellyPlus1PM
* <li>Type: Boolean
* <li>Level: WARN
* </ul>
*/
NEEDS_RESTART(Doc.of(Level.INFO) //
.text("Shelly suggests a restart.")),
/**
* Slave Communication Failed Fault.
*
* <ul>
* <li>Interface: ShellyPlus1PM
* <li>Type: State
* </ul>
*/
SLAVE_COMMUNICATION_FAILED(Doc.of(Level.FAULT)); //

private final Doc doc;

private ChannelId(Doc doc) {
this.doc = doc;
}

@Override
public Doc doc() {
return this.doc;
}
}

/**
* Gets the Channel for {@link ChannelId#RELAY}.
*
* @return the Channel
*/
public default BooleanWriteChannel getRelayChannel() {
return this.channel(ChannelId.RELAY);
}

/**
* Gets the Relay Output 1. See {@link ChannelId#RELAY}.
*
* @return the Channel {@link Value}
*/
public default Value<Boolean> getRelay() {
return this.getRelayChannel().value();
}

/**
* Internal method to set the 'nextValue' on {@link ChannelId#RELAY} Channel.
*
* @param value the next value
*/
public default void _setRelay(Boolean value) {
this.getRelayChannel().setNextValue(value);
}

/**
* Sets the Relay Output. See {@link ChannelId#RELAY}.
*
* @param value the next write value
* @throws OpenemsNamedException on error
*/
public default void setRelay(boolean value) throws OpenemsNamedException {
this.getRelayChannel().setNextWriteValue(value);
}

/**
* Gets the Channel for {@link ChannelId#SLAVE_COMMUNICATION_FAILED}.
*
* @return the Channel
*/
public default StateChannel getSlaveCommunicationFailedChannel() {
return this.channel(ChannelId.SLAVE_COMMUNICATION_FAILED);
}

/**
* Gets the Slave Communication Failed State. See
* {@link ChannelId#SLAVE_COMMUNICATION_FAILED}.
*
* @return the Channel {@link Value}
*/
public default Value<Boolean> getSlaveCommunicationFailed() {
return this.getSlaveCommunicationFailedChannel().value();
}

/**
* Internal method to set the 'nextValue' on
* {@link ChannelId#SLAVE_COMMUNICATION_FAILED} Channel.
*
* @param value the next value
*/
public default void _setSlaveCommunicationFailed(boolean value) {
this.getSlaveCommunicationFailedChannel().setNextValue(value);
}

}
Loading

0 comments on commit 514d5d4

Please sign in to comment.