Skip to content

Commit

Permalink
Merge pull request #8 from xprojects-de/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
xprojects-de authored Oct 8, 2020
2 parents 15cf91a + cb6bccf commit 5d0b0b4
Show file tree
Hide file tree
Showing 12 changed files with 407 additions and 111 deletions.
103 changes: 98 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,103 @@
# Alpdesk-Automationservice
Java-Service for Automation (like Homeautomation)

To start on RaspberryPi with Shell-Script:
1)
Install Rasspbian PI OS Lite on RaspberryPi

2)
To enable ssh at first Boot create an empty file named "ssh" directly on the SD-Card using your PC

3)
Boot RaspberryPi from SD-Card and login using "ssh pi@PIIP"
Default-PW is "raspberry"

4)
change pi and root PW by "sudo passwd root" and "sudo passwd pi"

5)
Make updates by "sudo apt update" and "sudo apt upgrade" and reboot after update process by "sudo reboot"

6)
Relogin using SSH and run "sudo raspi-config"
DO following settings:
- Advandced Options > Expand Filesystem
- Interface Options > SSH > enable
Reboot pi

7)
Install Java 11 and lighttpd Webserver
- sudo apt install default-jdk
- sudo apt install lighttpd
After that "java -version" shoudl show V11 and unter /var/www/html you can put the Web-Client from https://github.com/xprojects-de/alpdesk-automationclient under Releases
Do not forget to modify the assests/config_dev.json with right IP of Pi and you custom IDs for REST-View
Maybe to upload you have to set "sudo chmod -R 0777 /var/www/html" (not recommended)

8)
create a dir /home/pi/alpdesk
create file startAlpdeskAutomationservice.sh and add following content:
-----

#!/bin/sh
cd /home/pi/xhomeautomation
mount /dev/sda1 /media/xhomeautomationusb/
sudo mount | grep sda1
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5001 -jar Alpdesk-Automationservice-Deploy.jar /home/pi/xhomeautomation/homeautomation.properties --spring.profiles.active=prod --spring.datasource.url=jdbc:h2:file:/media/xhomeautomationusb/xhomeautomationdb_prod
cd /home/pi/alpdesk
# Option when database should be stored to USB-Device
# mount /dev/sda1 /media/alpdeskusb/
# sudo mount | grep sda1
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5001 -jar Alpdesk-Automationservice-Deploy.jar /home/pi/alpdesk/alpdesk.properties --spring.profiles.active=prod --spring.datasource.url=jdbc:h2:file:/home/pi/alpdesk/alpdeskdb_prod

-----

9)
Make startAlpdeskAutomationservice.sh executeable by "sudo chmod 0777 startAlpdeskAutomationservice.sh"

10)
Upload files to /home/pi/alpdesk you can get from this Repo under Releases and example files under src/main/resources
- Alpdesk-Automationservice-Deploy.jar
- alpdesk.properties (Config-Properties-File)
- alpdesk.xml (Your Device-Config)
Modify you alpdesk.xml and alpdesk.properties as you want

11)
create a file named "autostart-alpdeskservice" under /etc/init.d/ with following content:

-----

#! /bin/sh
### BEGIN INIT INFO
# Provides: autostart-alpdeskservice
# Required-Start: $srart
# Required-Stop: $shutdown
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Starting Alpdesk-Service
# Description:
### END INIT INFO

case "$1" in
start)
echo "starting Alpdesk-Service"
sh /home/pi/alpdesk/startAlpdeskAutomationservice.sh >> "/home/pi/alpdesk/AlpdeskService.log" 2>&1 &
;;
stop)
echo "nothing to do"
;;
*)
echo "Use: /etc/init.d/autostart-alpdeskservice {start|stop}"
exit 1
;;
esac

exit 0

-----

make autostart-alpdeskservice executable by "sudo chmod 0777 /etc/init.d/autostart-alpdeskservice"

12)
add Sevice for autostart-alpdeskservice
- cd /etc/init.d
- sudo update-rc.d autostart-alpdeskservice defaults
- Reboot (after that the Service shpuld start at boot)

13) OPTIONAL
- Set a static IP by editing /etc/dhcpcd.conf
- Enable OverlayFS and RO /boot by "sudo raspi-config" and OverlayFS
5 changes: 3 additions & 2 deletions src/main/java/x/Devices/AnalogInDevice.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ public class AnalogInDevice extends BaseDevice {
@PropertyInfo(handle = 1, displayName = "Value", type = Types.TYPE_PROPERTIEINFO_INFO)
public float valueVisu = 0;

private int value = 0;
private float value = 0;

private String math = "";

public AnalogInDevice(int cycleTime) {
Expand All @@ -31,7 +32,7 @@ public void setMath(String math) {

@Override
public void receiveMessage(Object message) {
value = (int) ((short) ((int) message)); // Zweierkomplement => 65535 -> -1
value = (float) message;
valueVisu = MathParser.parse(value, math);
logger.debug("ANALOG_IN <" + id + "> => <" + value + "> <" + valueVisu + "> <" + label + ">");
super.receiveMessage(message);
Expand Down
76 changes: 76 additions & 0 deletions src/main/java/x/bus/BaseBus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package x.bus;

import java.lang.reflect.Field;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import x.DeviceUtils.DeviceListUtils;
import x.Devices.BaseDevice;
import x.Devices.OutputDevice;
import x.MessageHandling.MessageHandler;
import x.utils.DashboardInfo;
import x.utils.FieldParser;
import x.utils.PropertyInfo;
import x.websocket.model.AsyncStatusMessage;

public class BaseBus {

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

public void start() {

}

public void updateDeviceHandleStatusForWebSocket(int cycleTime, long elapsedTime, long worstCycleTime) {
AsyncStatusMessage globalASM = new AsyncStatusMessage();
globalASM.setKind(AsyncStatusMessage.MULTISET);
globalASM.setError(AsyncStatusMessage.NOERROR);
globalASM.getAsm().add(new AsyncStatusMessage(AsyncStatusMessage.NOERROR, AsyncStatusMessage.SET, "-10", cycleTime + "|" + elapsedTime + "|" + worstCycleTime));
//MessageHandler.getInstance().messageToWebSocketClients(new AsyncStatusMessage(AsyncStatusMessage.NOERROR, AsyncStatusMessage.SET, "-10", cycleTime + "|" + elapsedTime + "|" + worstCycleTime));
for (Object deviceHandle : DeviceListUtils.getInstance().getDeviceList()) {
if (deviceHandle instanceof OutputDevice) {
globalASM.getAsm().add(new AsyncStatusMessage(AsyncStatusMessage.NOERROR, AsyncStatusMessage.SET, "" + ((OutputDevice) deviceHandle).deviceHandle, (((OutputDevice) deviceHandle).isValue() == true ? "1" : "0")));
//MessageHandler.getInstance().messageToWebSocketClients(new AsyncStatusMessage(AsyncStatusMessage.NOERROR, AsyncStatusMessage.SET, "" + ((OutputDevice) deviceHandle).deviceHandle, (((OutputDevice) deviceHandle).isValue() == true ? "1" : "0")));
}
Field[] fields = deviceHandle.getClass().getFields();
for (Field f : fields) {

// PropertyInfos
PropertyInfo p = (PropertyInfo) f.getAnnotation(PropertyInfo.class);
if (p != null) {
try {
String value2Send = FieldParser.convertField(f, deviceHandle);
if (p.stateful()) {
if (FieldParser.convertFieldState(f, deviceHandle)) {
value2Send = value2Send + "|xactive";
}
}
//MessageHandler.getInstance().messageToWebSocketClients(new AsyncStatusMessage(AsyncStatusMessage.NOERROR, AsyncStatusMessage.SET, "p" + ((BaseDevice) deviceHandle).deviceHandle + "_" + p.handle(), value2Send));
globalASM.getAsm().add(new AsyncStatusMessage(AsyncStatusMessage.NOERROR, AsyncStatusMessage.SET, "p" + ((BaseDevice) deviceHandle).deviceHandle + "_" + p.handle(), value2Send));
} catch (Exception e) {
logger.error(e.getMessage());
}
}

// DashboardInfos
if (((BaseDevice) deviceHandle).dashboard == true) {
DashboardInfo d = (DashboardInfo) f.getAnnotation(DashboardInfo.class);
if (d != null) {
try {
String value2Send = FieldParser.convertField(f, deviceHandle);
if (d.stateful()) {
if (FieldParser.convertFieldState(f, deviceHandle)) {
value2Send = value2Send + "|xactive";
}
}
//MessageHandler.getInstance().messageToWebSocketClients(new AsyncStatusMessage(AsyncStatusMessage.NOERROR, AsyncStatusMessage.SET, "d" + ((BaseDevice) deviceHandle).deviceHandle + "_" + d.handle(), value2Send));
globalASM.getAsm().add(new AsyncStatusMessage(AsyncStatusMessage.NOERROR, AsyncStatusMessage.SET, "d" + ((BaseDevice) deviceHandle).deviceHandle + "_" + d.handle(), value2Send));
} catch (Exception e) {
logger.error(e.getMessage());
}
}
}
}
}
MessageHandler.getInstance().messageToWebSocketClients(globalASM);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package x.modbus;
package x.bus;

import java.lang.reflect.Field;
import java.util.Random;
import net.wimpi.modbus.Modbus;
import net.wimpi.modbus.ModbusException;
Expand All @@ -16,18 +15,12 @@
import x.Devices.InputDevice;
import x.Devices.OutputDevice;
import x.Devices.TemperatureDevice;
import x.Devices.BaseDevice;
import x.Devices.DimmerDevice;
import x.Devices.SensorTemperatureDevice;
import x.MessageHandling.MessageHandler;
import x.utils.DashboardInfo;
import x.utils.PropertyInfo;
import x.utils.FieldParser;
import x.websocket.model.AsyncStatusMessage;

public class XModbusMaster {
public class ModbusMasterHomeautomation extends BaseBus {

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

private int cycleTime = 75;
private long worstCycleTime = 75;
Expand All @@ -46,7 +39,7 @@ public class XModbusMaster {
public static final int modbusAnalogOutputOffset = 0x200;
private static final int modbusUnitID = 1;

public XModbusMaster(String modbusIP, boolean simulation, int cycleTimeMS) {
public ModbusMasterHomeautomation(String modbusIP, boolean simulation, int cycleTimeMS) {
this.modbusHost = modbusIP;
this.simulation = simulation;
this.cycleTime = cycleTimeMS;
Expand Down Expand Up @@ -88,6 +81,7 @@ private void connectModbus(boolean reconnect) {
}
}

@Override
public void start() {
connectModbus(false);
if (modBusInit == true) {
Expand Down Expand Up @@ -124,7 +118,7 @@ public void start() {
}

if (cyclicCounter % 50 == 0) {
updateDeviceHandleStatusForWebSocket();
updateDeviceHandleStatusForWebSocket(cycleTime, elapsedTime, worstCycleTime);
}

if (cyclicCounter >= 1000) {
Expand Down Expand Up @@ -155,7 +149,7 @@ private void readModbusDigitalInputs() throws ModbusException {
int max = DeviceListUtils.getInstance().getMaxInputBusAddress();
if (max >= 0) {
int bitCount = max + 1;
bvInput = modbusMaster.readInputDiscretes(XModbusMaster.modbusDigitalInputOffset, bitCount);
bvInput = modbusMaster.readInputDiscretes(ModbusMasterHomeautomation.modbusDigitalInputOffset, bitCount);
for (int address = 0; address < bitCount; address++) {
for (Object deviceHandle : DeviceListUtils.getInstance().getDeviceList()) {
if (deviceHandle instanceof InputDevice) {
Expand All @@ -177,13 +171,13 @@ private void writeModbusDigitalOutputs() throws ModbusException {
int max = DeviceListUtils.getInstance().getMaxOutputBusAddress();
if (max >= 0) {
int bitCount = max + 1;
bvOutput = modbusMaster.readCoils(XModbusMaster.modbusDigitalOutputOffset, bitCount);
bvOutput = modbusMaster.readCoils(ModbusMasterHomeautomation.modbusDigitalOutputOffset, bitCount);
for (int address = 0; address < bitCount; address++) {
for (Object deviceHandle : DeviceListUtils.getInstance().getDeviceList()) {
if (deviceHandle instanceof OutputDevice) {
if (((OutputDevice) deviceHandle).busAddress == address) {
if (bvOutput.getBit(address) != ((OutputDevice) deviceHandle).isValue()) {
modbusMaster.writeCoil(XModbusMaster.modbusUnitID, ((OutputDevice) deviceHandle).busAddress, ((OutputDevice) deviceHandle).isValue());
modbusMaster.writeCoil(ModbusMasterHomeautomation.modbusUnitID, ((OutputDevice) deviceHandle).busAddress, ((OutputDevice) deviceHandle).isValue());
}
break;
}
Expand Down Expand Up @@ -257,58 +251,4 @@ private void writeModbusDimmerAnalogOutputs() throws ModbusException {
}
}
}

private void updateDeviceHandleStatusForWebSocket() {
AsyncStatusMessage globalASM = new AsyncStatusMessage();
globalASM.setKind(AsyncStatusMessage.MULTISET);
globalASM.setError(AsyncStatusMessage.NOERROR);
globalASM.getAsm().add(new AsyncStatusMessage(AsyncStatusMessage.NOERROR, AsyncStatusMessage.SET, "-10", cycleTime + "|" + elapsedTime + "|" + worstCycleTime));
//MessageHandler.getInstance().messageToWebSocketClients(new AsyncStatusMessage(AsyncStatusMessage.NOERROR, AsyncStatusMessage.SET, "-10", cycleTime + "|" + elapsedTime + "|" + worstCycleTime));
for (Object deviceHandle : DeviceListUtils.getInstance().getDeviceList()) {
if (deviceHandle instanceof OutputDevice) {
globalASM.getAsm().add(new AsyncStatusMessage(AsyncStatusMessage.NOERROR, AsyncStatusMessage.SET, "" + ((OutputDevice) deviceHandle).deviceHandle, (((OutputDevice) deviceHandle).isValue() == true ? "1" : "0")));
//MessageHandler.getInstance().messageToWebSocketClients(new AsyncStatusMessage(AsyncStatusMessage.NOERROR, AsyncStatusMessage.SET, "" + ((OutputDevice) deviceHandle).deviceHandle, (((OutputDevice) deviceHandle).isValue() == true ? "1" : "0")));
}
Field[] fields = deviceHandle.getClass().getFields();
for (Field f : fields) {

// PropertyInfos
PropertyInfo p = (PropertyInfo) f.getAnnotation(PropertyInfo.class);
if (p != null) {
try {
String value2Send = FieldParser.convertField(f, deviceHandle);
if (p.stateful()) {
if (FieldParser.convertFieldState(f, deviceHandle)) {
value2Send = value2Send + "|xactive";
}
}
//MessageHandler.getInstance().messageToWebSocketClients(new AsyncStatusMessage(AsyncStatusMessage.NOERROR, AsyncStatusMessage.SET, "p" + ((BaseDevice) deviceHandle).deviceHandle + "_" + p.handle(), value2Send));
globalASM.getAsm().add(new AsyncStatusMessage(AsyncStatusMessage.NOERROR, AsyncStatusMessage.SET, "p" + ((BaseDevice) deviceHandle).deviceHandle + "_" + p.handle(), value2Send));
} catch (Exception e) {
logger.error(e.getMessage());
}
}

// DashboardInfos
if (((BaseDevice) deviceHandle).dashboard == true) {
DashboardInfo d = (DashboardInfo) f.getAnnotation(DashboardInfo.class);
if (d != null) {
try {
String value2Send = FieldParser.convertField(f, deviceHandle);
if (d.stateful()) {
if (FieldParser.convertFieldState(f, deviceHandle)) {
value2Send = value2Send + "|xactive";
}
}
//MessageHandler.getInstance().messageToWebSocketClients(new AsyncStatusMessage(AsyncStatusMessage.NOERROR, AsyncStatusMessage.SET, "d" + ((BaseDevice) deviceHandle).deviceHandle + "_" + d.handle(), value2Send));
globalASM.getAsm().add(new AsyncStatusMessage(AsyncStatusMessage.NOERROR, AsyncStatusMessage.SET, "d" + ((BaseDevice) deviceHandle).deviceHandle + "_" + d.handle(), value2Send));
} catch (Exception e) {
logger.error(e.getMessage());
}
}
}
}
}
MessageHandler.getInstance().messageToWebSocketClients(globalASM);
}
}
Loading

0 comments on commit 5d0b0b4

Please sign in to comment.