forked from Pi4J/pi4j-v1
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Pi4J#32 Initial implementation for 1 Wire based devices using /sys/bu…
…s/w1
- Loading branch information
Showing
30 changed files
with
876 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package com.pi4j.io.w1; | ||
|
||
/* | ||
* #%L | ||
* ********************************************************************** | ||
* ORGANIZATION : Pi4J | ||
* PROJECT : Pi4J :: Java Library (Core) | ||
* FILENAME : W1Device.java | ||
* | ||
* This file is part of the Pi4J project. More information about | ||
* this project can be found here: http://www.pi4j.com/ | ||
* ********************************************************************** | ||
* %% | ||
* Copyright (C) 2012 - 2015 Pi4J | ||
* %% | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Lesser General Public License as | ||
* published by the Free Software Foundation, either version 3 of the | ||
* License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Lesser Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Lesser Public | ||
* License along with this program. If not, see | ||
* <http://www.gnu.org/licenses/lgpl-3.0.html>. | ||
* #L% | ||
*/ | ||
|
||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
|
||
/** | ||
* @author Peter Schuebl | ||
*/ | ||
public interface W1Device { | ||
|
||
/** | ||
* Returns the name (id/serial number) of the device e.g. 28-00000698ebb1. | ||
* @return the unique device name. | ||
*/ | ||
String getName(); | ||
|
||
String getId(); | ||
|
||
/** | ||
* Gets the gurrent Value = content of w1_slave file | ||
* @return | ||
*/ | ||
String getValue() throws IOException; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package com.pi4j.io.w1; | ||
|
||
/* | ||
* #%L | ||
* ********************************************************************** | ||
* ORGANIZATION : Pi4J | ||
* PROJECT : Pi4J :: Java Library (Core) | ||
* FILENAME : W1DeviceType.java | ||
* | ||
* This file is part of the Pi4J project. More information about | ||
* this project can be found here: http://www.pi4j.com/ | ||
* ********************************************************************** | ||
* %% | ||
* Copyright (C) 2012 - 2015 Pi4J | ||
* %% | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Lesser General Public License as | ||
* published by the Free Software Foundation, either version 3 of the | ||
* License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Lesser Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Lesser Public | ||
* License along with this program. If not, see | ||
* <http://www.gnu.org/licenses/lgpl-3.0.html>. | ||
* #L% | ||
*/ | ||
|
||
|
||
import java.io.File; | ||
|
||
/** | ||
* | ||
* http://en.wikipedia.org/wiki/1-Wire | ||
* @author Peter Schuebl | ||
*/ | ||
public interface W1DeviceType { | ||
|
||
/** | ||
* Returns the FID of the W1 device e.g. 0x28 for DS18B20 | ||
* | ||
* Each device has 48 bit (six bytes) globally unique address where last eight bits are | ||
* CRC of first 56 bits. First byte stores a device family code, that identifies device type. | ||
* | ||
* @return the family id of the device | ||
*/ | ||
int getDeviceFamilyCode(); | ||
|
||
/** | ||
* Gets the implementation class of the device which must be a sub-class of W1Device | ||
* @return the implementation class | ||
*/ | ||
Class<? extends W1Device> getDeviceClass(); | ||
|
||
/** | ||
* Creates a new instance of a concrete device. | ||
* @param deviceDir | ||
* @return | ||
*/ | ||
W1Device create(File deviceDir); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
package com.pi4j.io.w1; | ||
|
||
import java.io.File; | ||
import java.io.FilenameFilter; | ||
import java.util.*; | ||
import java.util.logging.Logger; | ||
|
||
/* | ||
* #%L | ||
* ********************************************************************** | ||
* ORGANIZATION : Pi4J | ||
* PROJECT : Pi4J :: Java Library (Core) | ||
* FILENAME : W1Master.java | ||
* | ||
* This file is part of the Pi4J project. More information about | ||
* this project can be found here: http://www.pi4j.com/ | ||
* ********************************************************************** | ||
* %% | ||
* Copyright (C) 2012 - 2015 Pi4J | ||
* %% | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Lesser General Public License as | ||
* published by the Free Software Foundation, either version 3 of the | ||
* License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Lesser Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Lesser Public | ||
* License along with this program. If not, see | ||
* <http://www.gnu.org/licenses/lgpl-3.0.html>. | ||
* #L% | ||
*/ | ||
public class W1Master { | ||
|
||
private final Logger log = Logger.getLogger(W1Master.class.getName()); | ||
|
||
private final List<W1DeviceType> deviceTypes = new ArrayList<>(); | ||
|
||
private final Map<String, W1DeviceType> deviceTypeMap = new LinkedHashMap<>(); | ||
|
||
private File masterDir = new File("/sys/bus/w1/devices"); | ||
|
||
/** | ||
* Create an instance of the W1 master. | ||
* Typically there should only be one master. | ||
* | ||
* java.util.ServiceLoader is used to add device support for individual devices. | ||
*/ | ||
public W1Master() { | ||
init(); | ||
} | ||
|
||
/** | ||
* Create a master with a different default dir e.g. for tests. | ||
* @param masterDir | ||
*/ | ||
public W1Master(final String masterDir) { | ||
this.masterDir = new File(masterDir); | ||
init(); | ||
} | ||
|
||
private void init() { | ||
final ServiceLoader<W1DeviceType> w1DeviceTypes = ServiceLoader.load(W1DeviceType.class); | ||
final Iterator<W1DeviceType> w1DeviceTypeIterator = w1DeviceTypes.iterator(); | ||
while (w1DeviceTypeIterator.hasNext()) { | ||
final W1DeviceType w1DeviceType = w1DeviceTypeIterator.next(); | ||
deviceTypes.add(w1DeviceType); | ||
final String deviceFamily = Integer.toHexString(w1DeviceType.getDeviceFamilyCode()).toUpperCase(); | ||
deviceTypeMap.put(deviceFamily, w1DeviceType); | ||
} | ||
} | ||
|
||
/** | ||
* Gets a list of the available device types. | ||
* @return | ||
*/ | ||
public Collection<W1DeviceType> getDeviceTypes() { | ||
return deviceTypes; | ||
} | ||
|
||
private List<File> getDeviceDirs() { | ||
final File[] slaveDevices = masterDir.listFiles(new FilenameFilter() { | ||
@Override | ||
public boolean accept(File dir, String name) { | ||
return !name.contains("w1_bus_master"); | ||
} | ||
}); | ||
return Arrays.asList(slaveDevices); | ||
} | ||
|
||
/** | ||
* Gets a list of all registered slave device ids. | ||
* @return list of slave ids, can be empty, never null. | ||
*/ | ||
public List<String> getDeviceIDs() { | ||
List<String> ids = new ArrayList<>(); | ||
for (File deviceDir: getDeviceDirs()) { | ||
ids.add(deviceDir.getName()); | ||
} | ||
return ids; | ||
} | ||
|
||
public List<W1Device> getDevices() { | ||
return getDevices((String)null); | ||
} | ||
|
||
public List<W1Device> getDevices(int deviceFamilyId) { | ||
return getDevices(Integer.toHexString(deviceFamilyId)); | ||
} | ||
|
||
public <T extends W1Device> List<T> getDevices(String deviceFamilyId) { | ||
List<W1Device> devices = new ArrayList<>(); | ||
for (File deviceDir: getDeviceDirs()) { | ||
String id = deviceDir.getName().substring(0, 2).toUpperCase(); | ||
if (deviceFamilyId == null || deviceFamilyId.toUpperCase().equals(id)) { | ||
final W1DeviceType w1DeviceType = deviceTypeMap.get(id); | ||
if (w1DeviceType != null) { | ||
final W1Device w1Device = w1DeviceType.create(deviceDir); | ||
devices.add(w1Device); | ||
} else { | ||
log.info("no device type for [" + id + "] found - ignoring"); | ||
} | ||
} | ||
} | ||
return (List<T>) devices; | ||
} | ||
|
||
public <T extends W1Device> List<T> getDevices(Class<T> type) { | ||
for (W1DeviceType deviceType : deviceTypes) { | ||
if (deviceType.getDeviceClass().equals(type)) { | ||
return (List<T>) getDevices(deviceType.getDeviceFamilyCode()); | ||
} | ||
} | ||
return Collections.emptyList(); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
StringBuilder builder = new StringBuilder(); | ||
builder.append("W1 Master: ").append(masterDir).append("\n"); | ||
builder.append("Device Types: \n"); | ||
for (W1DeviceType deviceType : deviceTypeMap.values()) { | ||
builder.append(" - ").append(Integer.toHexString(deviceType.getDeviceFamilyCode())); | ||
builder.append(" = ").append(deviceType.getDeviceClass()); | ||
builder.append("\n"); | ||
} | ||
builder.append("Devices:\n"); | ||
for (W1Device device : getDevices()) { | ||
builder.append(" - ").append(device.getId()).append(": ").append(device.getName()); | ||
builder.append(" = ").append(device.getClass().getName()).append("\n"); | ||
} | ||
return builder.toString(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/** | ||
* http://lxr.free-electrons.com/source/drivers/w1/slaves/w1_therm.c | ||
* http://lxr.free-electrons.com/source/drivers/w1/w1_family.h | ||
* @author Peter Schuebl | ||
*/ | ||
package com.pi4j.io.w1; | ||
|
||
/* | ||
* #%L | ||
* ********************************************************************** | ||
* ORGANIZATION : Pi4J | ||
* PROJECT : Pi4J :: Java Library (Core) | ||
* FILENAME : package-info.java | ||
* | ||
* This file is part of the Pi4J project. More information about | ||
* this project can be found here: http://www.pi4j.com/ | ||
* ********************************************************************** | ||
* %% | ||
* Copyright (C) 2012 - 2015 Pi4J | ||
* %% | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Lesser General Public License as | ||
* published by the Free Software Foundation, either version 3 of the | ||
* License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Lesser Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Lesser Public | ||
* License along with this program. If not, see | ||
* <http://www.gnu.org/licenses/lgpl-3.0.html>. | ||
* #L% | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package com.pi4j.io.w1; | ||
|
||
/* | ||
* #%L | ||
* ********************************************************************** | ||
* ORGANIZATION : Pi4J | ||
* PROJECT : Pi4J :: Java Library (Core) | ||
* FILENAME : W1DummyDevice.java | ||
* | ||
* This file is part of the Pi4J project. More information about | ||
* this project can be found here: http://www.pi4j.com/ | ||
* ********************************************************************** | ||
* %% | ||
* Copyright (C) 2012 - 2015 Pi4J | ||
* %% | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Lesser General Public License as | ||
* published by the Free Software Foundation, either version 3 of the | ||
* License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Lesser Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Lesser Public | ||
* License along with this program. If not, see | ||
* <http://www.gnu.org/licenses/lgpl-3.0.html>. | ||
* #L% | ||
*/ | ||
|
||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
|
||
/** | ||
* @author Peter Schuebl | ||
*/ | ||
public class W1DummyDevice implements W1Device { | ||
|
||
private String name; | ||
|
||
private File deviceDir; | ||
|
||
@Override | ||
public String getName() { | ||
return name; | ||
} | ||
|
||
@Override | ||
public String getId() { | ||
return deviceDir.getName(); | ||
} | ||
|
||
public W1DummyDevice(final File deviceDir) { | ||
try { | ||
name = new String(Files.readAllBytes(new File(deviceDir, "name").toPath())); | ||
} catch (IOException e) { | ||
// FIXME logging | ||
name = deviceDir.getName(); | ||
} | ||
this.deviceDir = deviceDir; | ||
} | ||
|
||
@Override | ||
public String getValue() throws IOException { | ||
return new String(Files.readAllBytes(new File(deviceDir, "w1_slave").toPath())); | ||
} | ||
} |
Oops, something went wrong.
b76d065
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work! What do you think about adding a WatchService to auto-detect added/removed 1-wire devices and send events to listeners?
b76d065
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks.
Yes, that sounds good. The code could do with some more documentation as well.
I don't have any other W1 devices but the ServiceLoader approach should allow adding new devices in library jars without adding to the core.
I'll have a look at the WatchService - should be relatively easy to implement.