Först behöver du skapa en databas med lite tabeller.
MySQL-Script
Kod: Markera allt
CREATE DATABASE 1wire;
USE 1wire;
CREATE USER '1wireuser'@'%' IDENTIFIED BY '1wirepassword';
GRANT USAGE ON * . * TO '1wireuser'@'%';
GRANT ALL PRIVILEGES ON 1wire . * TO '1wireuser'@'%';
CREATE TABLE IF NOT EXISTS 1wiresensors (
id int(11) NOT NULL AUTO_INCREMENT,
sensorpath varchar(24) NOT NULL,
enabled tinyint(1) NOT NULL,
name varchar(64) NOT NULL,
LowTempReport tinyint(1) NOT NULL,
SwitchKingID int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (id)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS 1wirevalues (
id int(11) NOT NULL AUTO_INCREMENT,
reporttime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
sensorid int(11) NOT NULL,
sensorvalue float NOT NULL,
PRIMARY KEY (id),
KEY sensorid (sensorid),
KEY rptTime (reporttime)
) ENGINE=InnoDB;
ALTER TABLE 1wirevalues
ADD CONSTRAINT 1wirevalues_ibfk_1 FOREIGN KEY (sensorid) REFERENCES 1wiresensors (id) ON DELETE CASCADE ON UPDATE CASCADE;
CREATE VIEW vSensorValues AS
SELECT
1wiresensors.name AS name,
1wirevalues.reporttime AS reporttime,
1wirevalues.sensorvalue AS sensorvalue
FROM (1wiresensors JOIN 1wirevalues ON (1wirevalues.sensorid = 1wiresensors.id) );
Kod: Markera allt
-- Dummy sensors
INSERT INTO 1wiresensors (sensorpath, enabled, name, LowTempReport, SwitchKingID) VALUES ('10.123456789100', 1, 'Utomhus Öster', 1, 10);
INSERT INTO 1wiresensors (sensorpath, enabled, name, LowTempReport, SwitchKingID) VALUES ('10.123123123123', 1, 'Utomhus Väster', 1, 11);
INSERT INTO 1wiresensors (sensorpath, enabled, name, LowTempReport, SwitchKingID) VALUES ('10.232323232323', 1, 'Köket', 0, 12);
INSERT INTO 1wiresensors (sensorpath, enabled, name, LowTempReport, SwitchKingID) VALUES ('10.929292929292', 1, 'Sovrum', 0, 13);
INSERT INTO 1wiresensors (sensorpath, enabled, name, LowTempReport, SwitchKingID) VALUES ('10.999999999999', 0, 'Test Sensor', 0, 0);
-- Dummy values
INSERT INTO 1wirevalues (sensorid, sensorvalue) VALUES (1, 11);
INSERT INTO 1wirevalues (sensorid, sensorvalue) VALUES (1, 12);
INSERT INTO 1wirevalues (sensorid, sensorvalue) VALUES (1, 13);
INSERT INTO 1wirevalues (sensorid, sensorvalue) VALUES (2, 1);
INSERT INTO 1wirevalues (sensorid, sensorvalue) VALUES (2, 2);
INSERT INTO 1wirevalues (sensorid, sensorvalue) VALUES (2, 3);
INSERT INTO 1wirevalues (sensorid, sensorvalue) VALUES (3, -10);
INSERT INTO 1wirevalues (sensorid, sensorvalue) VALUES (3, -11);
INSERT INTO 1wirevalues (sensorid, sensorvalue) VALUES (3, -12);
Uppdatera sensors-tabellen med rätt SwitchKing ID för datakälla/sensor. Det är alltså en datakälla per sensor.
När du ändå har SwitchKing igång, passa på att skapa en extra källa "Min temp utomhus".
(ID't på den källan ska in i PHP-scriptet)
Sen skapar du ett PHP-script som läser sensor-tabellen och skriver in datat i values-tabellen... och när scriptet ändå har läst av 1-wire nätet så passar den vidare informationen till SwitchKing och Temperatur.nu.
nano /data/read1wire.php
Kod: Markera allt
<?
// OWFS
define("OWFS_MOUNTPOINT", "/mnt/1wire/");
// MySQL Database
define("DB_USER", "1wireuser");
define("DB_PASSWORD", "1wirepassword");
define("DB_DATABASE", "1wire");
define("DB_SERVER", "127.0.0.1");
// SwitchKing REST API
define("SK_ENABLED", true);
define("SK_REST_SERVER", 127.0.0.1");
define("SK_REST_PORT", "8800");
define("SK_REST_USER", "UserName");
define("SK_REST_PASS", "SomePassword");
// LowTemp: Need XX sensors to report low temp
define("LOWTEMP_MINOK", 1);
// LowTemp: temperatur.nu
define("TMPNU_ENABLED", true);
define("TMPNU_STATION", "minstation");
define("TMPNU_ID", "123123123");
// LowTemp: SwitchKing DataSource ID
define("SK_LOWTEMP_ID", "44");
// ---------------------------------------------------------------------------------------------------------
// Other stuff...
define('CRLF', "\r\n");
define('TAB', "\t");
function openDb() {
global $dbConnection;
$options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
try {
$dbConnection = new PDO('mysql:dbname=' . DB_DATABASE . ';host=' . DB_SERVER, DB_USER, DB_PASSWORD, $options);
} catch (PDOException $err) {
echo ('Connection failed: ' . $err->getMessage());
$dbConnection = null;
}
}
function updateSwitchKing($id, $temp) {
if (SK_ENABLED) {
echo "SwitchKing: Adding value " . $temp . " for id " . $id . CRLF;
$context = stream_context_create(array(
'http' => array(
'header' => "Authorization: Basic " . base64_encode(SK_REST_USER . ":" . SK_REST_PASS)
)
));
$url = "http://" . SK_REST_SERVER . ":" . SK_REST_PORT . "/Datasources/" . $id . "/addvalue?value=" . $temp;
$data = file_get_contents($url, false, $context);
$xml = simplexml_load_string($data);
if ($xml->Successfull == "true") {
echo "SwitchKing: Successfull" . CRLF;
return true;
} else {
echo "SwitchKing: Error! " . $xml->Info . CRLF;
return false;
}
} else {
echo "SwitchKing: Disabled - Not reporting " . $temp . " for sensor " . $id . CRLF;
}
}
function updateSqlTemp($sensorId, $temp) {
echo "SQL: Adding temp " . $temp . " for sensor " . $sensorId . CRLF;
try {
// Add to MySQL
global $dbConnection;
$stmt = $dbConnection->prepare("INSERT INTO 1wirevalues (sensorid, sensorvalue) VALUES (:sensorId, :sensorValue)");
$stmt->bindValue(":sensorId", $sensorId, PDO::PARAM_STR);
$stmt->bindValue(":sensorValue", $temp, PDO::PARAM_STR);
$stmt->execute();
} catch (PDOException $err) {
echo "SQL: Failed: " . $err->getMessage() . CRLF;
return false;
}
echo "SQL: OK!" . CRLF;
return true;
}
function updateTemperaturNu($temp) {
if (TMPNU_ENABLED) {
echo "Temperatur.nu: Reporting temp " . $temp . CRLF;
// Post to Temperatur.nu
$url = "http://www.temperatur.nu/report/puttemp.php?s=" . TMPNU_STATION . "&id=" . TMPNU_ID . "&t=" . $temp;
$data = file_get_contents($url);
if (strpos($data, "ok!") === false) {
echo "Temperatur.nu: Not OK " . $data . CRLF;
} else {
echo "Temperatur.nu: OK " . CRLF;
}
} else {
echo "Temperatur.nu: Disabled - Not reporting " . $temp . CRLF;
}
}
function closeDb() {
global $dbConnection;
$dbConnection = null;
}
function readSensor($sensorpath) {
$fileName = OWFS_MOUNTPOINT . $sensorpath . "/temperature";
if (file_exists($fileName)) {
$data = trim(file_get_contents($fileName));
return $data;
} else {
return $fileName . " - Not Found";
}
}
// --------------------------------------------------------------------------------------------------------------
openDb();
global $dbConnection;
$lowTemp = 999;
$lowTempSensorOk = 0;
$lowTempFail = 0;
syslog(LOG_INFO, "1-Wire Reader: Starting to read 1-Wire sensors ...");
foreach($dbConnection->query("SELECT * FROM 1wiresensors WHERE enabled = true") as $sensor) {
echo "Main: Reading sensor " . $sensor["sensorpath"] . " - " . $sensor["name"] . CRLF;
$temp = readSensor($sensor["sensorpath"]);
if (is_numeric($temp)) {
echo "Main: Temperature: " . $temp . CRLF;
// Store low temp
if ($sensor["LowTempReport"] == true) {
if ($temp <= $lowTemp) {
$lowTemp = $temp;
$lowTempSensorOk ++;
echo "LowTemp: Found new low temp " . $lowTemp . " Total OK sensors: " . $lowTempSensorOk . CRLF;
}
}
// Post to SwitchKing
updateSwitchKing($sensor["SwitchKingID"], $temp);
// Add to MySQL
updateSqlTemp($sensor["id"], $temp);
} else {
echo "Main: Failed to read: " . $temp . CRLF;
syslog(LOG_ERR, "1-Wire Reader: Failed to read: " . $temp);
if ($sensor["LowTempReport"] == true) {
$lowTempFail ++;
echo "Main: LowTempReport enabled sensor, total failcount: " . $lowTempFail . CRLF;
}
}
echo CRLF;
}
if ($lowTempSensorOk >= LOWTEMP_MINOK) {
echo "Main: LowTemp Reporting (OK sensors: " . $lowTempSensorOk . ", temp: " . $lowTemp . ")" . CRLF;
syslog(LOG_DEBUG, "1-Wire Reader: Reporting low temp: " . $lowTemp);
// Post to SwitchKing (LowTemp)
updateSwitchKing(SK_LOWTEMP_ID, $lowTemp);
// Post to Temperatur.nu
updateTemperaturNu($lowTemp);
} else {
echo "Main: LowTemp Disabled, only " . $lowTempSensorOk . " sensors OK, failed to read: " . $lowTempFail . CRLF;
syslog(LOG_ERR, "1-Wire Reader: Failcount on low temp is " . $lowTempFail . " ... reporing aborted.");
}
closeDb();
syslog(LOG_INFO, "1-Wire Reader: Done reading 1-Wire sensors ...");
echo CRLF;
exit;
?>
LOWTEMP_MINOK - Minsta antalet sensorer med LowTempReport satt till 1 som ska vara tillgängliga för att rapportering av lägsta temp skall göras.
SK_LOWTEMP_ID - IDt i SwitchKing som lägsta temp skall tryckas in.
Sen ett litet shell-script för att köra PHP-snurran (vill inte köra flera instanser av den parallelt):
nano /data/read1wire.sh
Kod: Markera allt
#!/bin/sh
SCRIPTNAME=`basename $0`
PIDFILE=/var/run/${SCRIPTNAME}.pid
# Kolla om PID-filen finns
if [ -f ${PIDFILE} ]; then
# Lever processen?
OLDPID=`cat ${PIDFILE}`
RESULT=`ps -ef | grep ${OLDPID} | grep ${SCRIPTNAME}`
if [ -n "${RESULT}" ]; then
echo "Script already running! Exiting"
exit 255
fi
fi
# Skapa PID-fil
echo $$ > ${PIDFILE}
# Kör PHP och läs av 1-wire nätet
/usr/bin/php /data/read1wire.php
# Ta bort PID-filen
if [ -f ${PIDFILE} ]; then
rm ${PIDFILE}
fi
Kod: Markera allt
chmod +x /data/read1wire.sh
Och sedan ska det så klart köras via crontab'en, var 3e minut kanske blir lagomt?
crontab -e
Kod: Markera allt
*/3 * * * * /data/read1wire.sh
... hoppas jag inte missade en massa småsaker nu ...
