From e5e5918ba5f47e4f16936d2c37b30b2c71fed6de Mon Sep 17 00:00:00 2001 From: Mark Coombes Date: Thu, 8 Mar 2018 21:37:53 -0500 Subject: [PATCH] Control screen with mqtt Subscribe to prefix/screen to turn screen on with ON message, off with OFF message; declare last_input globally; create new #define for SCREEN; add callback for mqtt subscription; move lseek and read of screen to inside while loop. Update README.md with screen info and fix typos. --- README.md | 24 ++++++++++++++++-------- wink-handler.c | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 3c3dda5..d36916b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ wink-handler ============ -This is a simple app that can be run on a Wink Relay to turn it into a generic MQTT device. It will send button pushes and sensor data to the configured MQTT server, and will accept commands to turn on and off the built-in relays. +This is a simple app that can be run on a Wink Relay to turn it into a generic MQTT device. It will send button pushes and sensor data to the configured MQTT server, and will accept commands to turn on and off the built-in relays and screen. Download -------- @@ -21,7 +21,7 @@ Installing You'll need adb access to a rooted Wink Relay. Disable the existing Wink control software by running ``` -pm disable http://com.quirky.android .wink.projectone +pm disable http://com.quirky.android.wink.projectone ``` as root. Remount /system read-write: @@ -39,7 +39,7 @@ rm /system/bin/edisonwink adb push wink-handler to /sdcard and then copy it over edisonwink and fix permissions: ``` -cp /sdcard/wink0handler /system/bin/edisonwink +cp /sdcard/wink-handler /system/bin/edisonwink chmod 755 /system/bin/edisonwink ``` @@ -64,8 +64,8 @@ user: Username used to authenticate to the MQTT broker (optional) password: Password used to authenticate to the MQTT broker (optional) clientid: Client ID passed to the broker (optional - Wink_Relay if not provided) topic_prefix: Prefix to the topics presented by the device (optional - Relay if not provided) -screen_timeout: Time in seconds until the screen turns off after a touch or proximity detection (optional - 10s if not provided) -switch_toggle: Whether pressing the switch should toggle the relay directly (optional - false if not provided) +screen_timeout: Time in seconds until the screen turns off after a touch or proximity detection (optional - 10s if not provided) +switch_toggle: Whether pressing the switch should toggle the relay directly (optional - false if not provided) send_switch: Whether pressing the switch should generate an MQTT message (optional - true if not provided) Finally, reset your Relay. @@ -140,7 +140,15 @@ Relay/relays/lower_state state topics. -Screen control --------------- +Screen +------ + +The screen will turn on if the screen is touched or if the proximity sensor is triggered. It can also be controlled via the + +``` +Relay/screen +``` + +command topic: "ON" turns the screen on, "OFF" turns the screen off. -The screen will automatically turn on if the screen is touched and off 10 seconds later. It will also turn on and remain on if the proximity sensor is triggered, turning off 10 seconds after the last proximity detection. +The screen will turn off 10 seconds after the last touch, proximity, or mqtt "ON" command by default. This duration can be configured via the `screen_timeout` parameter in mqtt.ini. diff --git a/wink-handler.c b/wink-handler.c index 8a7044b..469cd1c 100644 --- a/wink-handler.c +++ b/wink-handler.c @@ -27,8 +27,11 @@ struct configuration { static struct configuration config; +int last_input; + #define UPPER_RELAY "/sys/class/gpio/gpio203/value" #define LOWER_RELAY "/sys/class/gpio/gpio204/value" +#define SCREEN "/sys/class/gpio/gpio30/value" void toggle_relay(char *path) { @@ -79,6 +82,27 @@ void handle_relay2(MessageData *md) handle_relay(LOWER_RELAY, message->payload, message->payloadlen); } +void handle_screen(MessageData *md) +{ + int fd; + char power; + MQTTMessage *message = md->message; + + fd = open(SCREEN, O_RDWR); + lseek(fd, 0, SEEK_SET); + read(fd, &power, sizeof(power)); + + if (strncmp(message->payload, "ON", message->payloadlen) == 0) { + last_input = time(NULL); + power = '1'; + write(fd, &power, 1); + } else if (strncmp(message->payload, "OFF", message->payloadlen) == 0) { + power = '0'; + write(fd, &power, 1); + } + close(fd); +} + int mqtt_connect(Network *n, MQTTClient *c, char *buf, char *readbuf) { int ret; MQTTPacket_connectData data = MQTTPacket_connectData_initializer; @@ -158,7 +182,6 @@ int main() { int lswitchstate=1; char urelaystate=' '; char lrelaystate=' '; - int last_input = time(NULL); struct input_event event; unsigned char buf[100], readbuf[100]; char buffer[30]; @@ -174,6 +197,7 @@ int main() { char *prefix, topic[1024]; int timeout; + last_input = time(NULL); config.send_switch = true; if (ini_parse("/sdcard/mqtt.ini", config_handler, NULL) < 0) { @@ -206,9 +230,6 @@ int main() { write(relay1, &power, 1); write(relay2, &power, 1); - lseek(screen, 0, SEEK_SET); - read(screen, &power, sizeof(power)); - limits.rlim_cur = RLIM_INFINITY; limits.rlim_max = RLIM_INFINITY; setrlimit(RLIMIT_CORE, &limits); @@ -219,6 +240,9 @@ int main() { MQTTSubscribe(&c, topic, 0, handle_relay1); sprintf(topic, "%s/relays/lower", prefix); MQTTSubscribe(&c, topic, 0, handle_relay2); + sprintf(topic, "%s/screen", prefix); + MQTTSubscribe(&c, topic, 0, handle_screen); + while (1) { lseek(relay1, 0, SEEK_SET); @@ -317,6 +341,9 @@ int main() { lseek(prox, 0, SEEK_SET); read(prox, proxdata, sizeof(proxdata)); proximity = strtol(proxdata, NULL, 10); + lseek(screen, 0, SEEK_SET); + read(screen, &power, sizeof(power)); + if (proximity >= 5000) { last_input = time(NULL); if (power != '1') {