Skip to content

Commit

Permalink
Fixed work schedule editor issue when saving a schedule.
Browse files Browse the repository at this point in the history
Documented an MQTT example for the Arduino R4
  • Loading branch information
point85 committed Jan 9, 2024
1 parent ea14e9c commit e61ebe9
Show file tree
Hide file tree
Showing 10 changed files with 167 additions and 11 deletions.
2 changes: 1 addition & 1 deletion install-oee-domain-jar.bat
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ rmdir /Q /S C:\maven_repo\org\point85\oee-domain
call mvn -v
call mvn clean package
rem install jar in local repo
call mvn install:install-file -Dfile=./target/OEE-Domain-3.10.0.jar -DgroupId=org.point85 -DartifactId=oee-domain -Dversion=3.10.0 -Dpackaging=jar
call mvn install:install-file -Dfile=./target/OEE-Domain-3.10.1.jar -DgroupId=org.point85 -DartifactId=oee-domain -Dversion=3.10.1 -Dpackaging=jar
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>org.point85</groupId>
<artifactId>oee-domain</artifactId>
<version>3.10.0</version>
<version>3.10.1</version>
<packaging>jar</packaging>
<url>http://maven.apache.org</url>

Expand Down
12 changes: 10 additions & 2 deletions src/main/java/org/point85/domain/DomainUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ private DomainUtils() {
}

public static String getVersionInfo() {
return DomainLocalizer.instance().getLangString("version") + " 3.10.0, "
+ LocalDate.of(2023, 12, 27).format(DateTimeFormatter.ISO_DATE);
return DomainLocalizer.instance().getLangString("version") + " 3.10.1, "
+ LocalDate.of(2024, 1, 10).format(DateTimeFormatter.ISO_DATE);
}

// format a Duration
Expand Down Expand Up @@ -251,4 +251,12 @@ public static String gunzip(byte[] data) throws Exception {

return new String(bos.toByteArray());
}

public static String byteArrayToHex(byte[] byteArray) {
StringBuilder sb = new StringBuilder();
for (byte b : byteArray) {
sb.append(String.format("%02X ", b));
}
return sb.toString();
}
}
3 changes: 3 additions & 0 deletions src/main/java/org/point85/domain/http/HttpOeeClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

import com.google.gson.Gson;

/**
* Class for making HTTP GET and PUT requests
*/
public class HttpOeeClient {
// logger
private Logger logger = LoggerFactory.getLogger(HttpOeeClient.class);
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/org/point85/domain/http/HttpSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@
import org.point85.domain.collector.DataSourceType;
import org.point85.domain.dto.HttpSourceDto;

/**
* The HttpSource class represents an HTTP/HTTPS server as a source of
* application events.
*
*/
@Entity
@DiscriminatorValue(DataSourceType.HTTP_VALUE)

public class HttpSource extends CollectorDataSource {
// overloaded for HTTPS port
@Column(name = "END_PATH")
Expand Down
114 changes: 114 additions & 0 deletions src/main/java/org/point85/domain/mqtt/MqttOeeClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.io.FileInputStream;
import java.net.InetAddress;
import java.security.KeyStore;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
Expand Down Expand Up @@ -42,6 +43,10 @@ public class MqttOeeClient extends BaseMessagingClient {
private static final String TCP_PROTOCOL = "tcp://";
private static final String SSL_PROTOCOL = "ssl://";

// polling loop for replies
private static final int NUM_TRIES = 20;
private static final int RETRY_WAIT = 500;

// native client
private MqttClient mqttClient;

Expand All @@ -51,20 +56,42 @@ public class MqttOeeClient extends BaseMessagingClient {
// connection options
private MqttConnectOptions connectionOptions = new MqttConnectOptions();

// flag for response from publishing a message is available
private AtomicBoolean dataAvailable = new AtomicBoolean(false);

// the text of the message response
private String messageResponse;

public MqttOeeClient() {
connectionOptions.setAutomaticReconnect(true);
connectionOptions.setCleanSession(CLEAN_SESSION);
connectionOptions.setConnectionTimeout(10);
}

/**
* Register listener for replies
*
* @param listener {@link MqttMessageListener}
*/
public void registerListener(MqttMessageListener listener) {
this.eventListener = listener;
}

/**
* Remove the reply listener
*/
public void unregisterListener() {
this.eventListener = null;
}

/**
* Initialize the client
*
* @param hostName Broker name
* @param port Broker port
* @param listener {@link MqttMessageListener}
* @throws Exception Exception
*/
public void startUp(String hostName, int port, MqttMessageListener listener) throws Exception {
// connect to server
connect(hostName, port);
Expand Down Expand Up @@ -110,6 +137,12 @@ public void connect(String hostName, int port) throws Exception {
}
}

/**
* Subscribe to message replies
*
* @param qos {@link QualityOfService}
* @throws Exception Exception
*/
public void subscribeToEvents(QualityOfService qos) throws Exception {
mqttClient.subscribe(EVENT_TOPIC, (topic, msg) -> {
String json = new String(msg.getPayload());
Expand Down Expand Up @@ -140,6 +173,12 @@ public void subscribeToEvents(QualityOfService qos) throws Exception {
}
}

/**
* Subscribe to notification messages
*
* @param qos {@link QualityOfService}
* @throws Exception Exception
*/
public void subscribeToNotifications(QualityOfService qos) throws Exception {
mqttClient.subscribe(STATUS_TOPIC, (topic, msg) -> {
String json = new String(msg.getPayload());
Expand Down Expand Up @@ -173,9 +212,21 @@ public void subscribeToNotifications(QualityOfService qos) throws Exception {
}
}

/**
* Publish an ApplicationMessage to the topic with the specified
* QualityOfService
*
* @param topic Topic
* @param message {@link ApplicationMessage}
* @param qos {@link QualityOfService}
* @throws Exception Exception
*/
public void publish(String topic, ApplicationMessage message, QualityOfService qos) throws Exception {
String text = serialize(message);
publishMessage(topic, text, qos);
}

private void publishMessage(String topic, String text, QualityOfService qos) throws Exception {
MqttMessage mqttMessage = new MqttMessage();
mqttMessage.setQos(qos.getQos());
mqttMessage.setRetained(false);
Expand All @@ -188,6 +239,69 @@ public void publish(String topic, ApplicationMessage message, QualityOfService q
}
}

/**
* Publish a text message, then wait for a response message. A prior call to
* subscribeToTopic() is required.
*
* @param topic Topic to publish to
* @param text Payload of message
* @param qos {@link QualityOfService}
* @param maxWait Maximum time to wait in seconds
* @return Payload of message response
* @throws Exception Exception
*/
public String publishAndWait(String topic, String text, QualityOfService qos, int maxWait) throws Exception {
dataAvailable.set(false);
messageResponse = null;

// send the message
publishMessage(topic, text, qos);

// wait for response
long start = System.currentTimeMillis();

for (int i = 0; i < NUM_TRIES; i++) {
Thread.sleep(RETRY_WAIT);
long delta = (System.currentTimeMillis() - start) / 1000;

if (dataAvailable.get() || delta >= maxWait) {
// response has been received or timed out
break;
}
}

if (messageResponse == null || messageResponse.isEmpty()) {
logger.warn("No response to publishing the message was received within " + maxWait + " seconds.");
}
return messageResponse;
}

/**
* Subscribe to this topic
*
* @param topic Topic to subscribe to
* @throws Exception Exception
*/
public void subscribeToTopic(String topic) throws Exception {
mqttClient.subscribe(topic, (theTopic, msg) -> {
messageResponse = new String(msg.getPayload());

if (messageResponse != null && !messageResponse.isEmpty()) {
dataAvailable.set(true);
} else {
dataAvailable.set(false);
}

if (logger.isInfoEnabled()) {
logger.info("MQTT message received, topic: " + theTopic + ", payload:\n\t" + messageResponse);
}
});

if (logger.isInfoEnabled()) {
logger.info("Subscribed to topic " + topic);
}
}

/**
* Disconnect from the MQTT server
*
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/org/point85/domain/schedule/Rotation.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ public class Rotation extends Named implements Comparable<Rotation> {
@OneToMany(mappedBy = "rotation", cascade = CascadeType.ALL, orphanRemoval = true)
private final List<RotationSegment> rotationSegments = new ArrayList<>();

// teams
@OneToMany(mappedBy = "rotation", cascade = CascadeType.ALL, orphanRemoval = true)
private final List<Team> teams = new ArrayList<>();

// list of working and non-working days
@Transient
private List<TimePeriod> periods;
Expand Down Expand Up @@ -215,10 +219,24 @@ public WorkSchedule getWorkSchedule() {
return workSchedule;
}

/**
* Assign the work schedule to this rotation
*
* @param workSchedule {@link WorkSchedule}
*/
public void setWorkSchedule(WorkSchedule workSchedule) {
this.workSchedule = workSchedule;
}

/**
* Get the rotation's related teams
*
* @return List of {@link Team}
*/
public List<Team> getTeams() {
return this.teams;
}

@Override
public int compareTo(Rotation other) {
return getName().compareTo(other.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@ of this software and associated documentation files (the "Software"), to deal
import java.util.Objects;

import javax.persistence.AttributeOverride;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.point85.domain.dto.RotationSegmentDto;
Expand Down Expand Up @@ -61,7 +59,7 @@ public class RotationSegment extends KeyedObject implements Comparable<RotationS
private int sequence = 0;

// shift that starts this segment
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@ManyToOne
@JoinColumn(name = "SHIFT_KEY")
private Shift startingShift;

Expand Down
13 changes: 13 additions & 0 deletions src/main/java/org/point85/domain/schedule/Shift.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ public class Shift extends TimePeriod implements Comparable<Shift> {
@OneToMany(mappedBy = "shift", cascade = CascadeType.ALL, orphanRemoval = true)
private final List<Break> breaks = new ArrayList<>();

// shifts
@OneToMany(mappedBy = "startingShift", cascade = CascadeType.ALL, orphanRemoval = true)
private final List<RotationSegment> segments = new ArrayList<>();

/**
* Default constructor
*/
Expand Down Expand Up @@ -88,6 +92,15 @@ public List<Break> getBreaks() {
return this.breaks;
}

/**
* Get the rotations segments for this shift
*
* @return List {@link RotationSegment}
*/
public List<RotationSegment> getRotationSegments() {
return this.segments;
}

/**
* Add a break period to this shift
*
Expand Down
4 changes: 1 addition & 3 deletions src/main/java/org/point85/domain/schedule/Team.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,10 @@ of this software and associated documentation files (the "Software"), to deal
import java.util.Objects;

import javax.persistence.AttributeOverride;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.point85.domain.DomainUtils;
Expand Down Expand Up @@ -65,7 +63,7 @@ public class Team extends Named implements Comparable<Team> {
private LocalDate rotationStart;

// shift rotation days
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@ManyToOne
@JoinColumn(name = "ROTATION_KEY")
private Rotation rotation;

Expand Down

0 comments on commit e61ebe9

Please sign in to comment.