This repository has been archived by the owner on Jun 13, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
SmarterCoffee.php
128 lines (110 loc) · 2.86 KB
/
SmarterCoffee.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<?php
class SmarterCoffee
{
protected $address;
protected $port;
protected $cups;
protected $strength;
protected $grind; // true for grind, false for filter
protected $carafe;
const ACTION_BREW = "7";
const ACTION_RESET = "\x10";
const ACTION_TOGGLE_GRIND = "\x3c\x7e";
const ACTION_SET_STRENGTH = "\x35%s\x7e";
const ACTION_SET_CUPS = "\x36%s\x7e";
const BUFFER_LENGTH = 10;
const RESULT_SUCCESS = 1;
const RESULT_NOOP = 2;
const RESULT_CARAFE_NOT_PRESENT = 4;
const RESULT_NO_WATER = 8;
const RESULT_BREW_IN_PROGRESS = 16;
const RESULT_UNKNOWN = 32;
public function __construct($address, $port = 2081) {
$this->address = $address;
$this->port = $port;
return $this;
}
public function brew() {
return $this->send(self::ACTION_BREW);
}
public function reset() {
return $this->send(self::ACTION_RESET);
}
public function setCups($cups) {
if (!is_null($this->cups) && $this->cups == $cups) {
return self::RESULT_NOOP;
}
$cups = max(1, $cups);
$cups = min(12, $cups);
return $this->send(
sprintf(self::ACTION_SET_CUPS, chr($cups))
);
}
public function setStrength($strength) {
if (!is_null($this->strength) && $this->strength == $strength) {
return self::RESULT_NOOP;
}
$strength = max(0, $strength);
$strength = min(2, $strength);
return $this->send(
sprintf(self::ACTION_SET_STRENGTH, chr($strength))
);
}
public function setGrind($grind) {
if (is_null($this->grind)) {
$this->toggleGrind();
}
if ($this->grind != $grind) {
return $this->toggleGrind();
}
return self::RESULT_SUCCESS;
}
protected function toggleGrind() {
return $this->send(self::ACTION_TOGGLE_GRIND);
}
protected function send($command) {
try {
$sc = fsockopen($this->address, $this->port);
fwrite($sc, $command);
$message = $this->parse(fgets($sc, self::BUFFER_LENGTH));
}
finally {
@fclose($sc);
}
return $message;
}
protected function parse($output) {
// [0] to [2] are the response code from the last command
// [3] to [9] are the status codes for the machine
$output = bin2hex($output);
$result = substr($output, 0, 6);
$status = substr($output, 6);
$this->parseStatus($status);
return $this->parseResult($result);
}
protected function parseResult($result) {
switch ($result) {
case "03007e":
return self::RESULT_SUCCESS;
case "03017e":
return self::RESULT_BREW_IN_PROGRESS;
case "03057e":
return self::RESULT_CARAFE_NOT_PRESENT;
case "03067e":
return self::RESULT_NO_WATER;
default:
return self::RESULT_UNKNOWN;
}
}
protected function parseStatus($status) {
$status = str_split($status, 2);
$status = array_map(function($elem) {
return hexdec($elem);
}, $status);
$this->carafe = (bool)($status[1] & 1);
$this->grind = (bool)($status[1] & 2);
$this->strength = $status[4];
$this->cups = $status[5] - 64;
// $status[2] is water level
}
}