Skip to content

Commit

Permalink
Merge branch 'main' of github.com:pascal-fb-martin/orvibo into main
Browse files Browse the repository at this point in the history
  • Loading branch information
pascal-fb-martin committed Dec 27, 2020
2 parents 1207896 + fd22f22 commit 9649fdd
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 2 deletions.
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ LIBOJS=

SHARE=/usr/local/share/house

all: orvibo
all: orvibo orvibosetup

clean:
rm -f *.o *.a orvibo
Expand All @@ -17,6 +17,9 @@ rebuild: clean all
orvibo: $(OBJS)
gcc -g -O -o orvibo $(OBJS) -lhouseportal -lechttp -lssl -lcrypto -lgpiod -lrt

orvibosetup: orvibosetup.o
gcc -g -O -o orvibosetup orvibosetup.o

install:
if [ -e /etc/init.d/orvibo ] ; then systemctl stop orvibo ; fi
mkdir -p /usr/local/bin
Expand Down
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# orvibo
A House web service to read and control Orvibo WiFi plugs
A House web service to read and control Orvibo S20 WiFi plugs
## Overview
This is a web server to give access to Ovibo WiFi electric plugs. This server can sense the current status and control the state of each plug. The web API is meant to be compatible with the House control API (e.g. the same web API as [houserelays](https://github.com/pascal-fb-martin/houserelays)).
## Warning
The Orvibo S20 is a discontinued model. Newer Orvibo models do not use the same protocol and this program is not compatible with them.
## Installation
* Install the OpenSSL development package(s).
* Install [echttp](https://github.com/pascal-fb-martin/echttp).
Expand Down Expand Up @@ -30,3 +32,22 @@ Each plug must be declared in file /etc/house/orvibo.json. A typical example of
}
}
```
## S20 Setup
The web service comes with a small command line tool to configure the Orvibo S20 for the local WiFi network, called orvibosetup:
```
orvibosetup <ssid>
```
The tool first asks for the WiFi password (without echoing it) and then proceeds with the setup. The S20 must already be accessible from the computer (typically if you plan on changing your WiFi password). If it is not, follow the steps below to connect the device:
* Plug the S20 device in a nearby outlet.
* Press the button until it flashes red at high speed, then release the button.
* Press the button again until it flashes blue at high speed, then release the button.
* On your computer, connect to the WiFi SSID "WiWo-S20" (no password).

Once the device and the computer are connected to each other, launch orvibosetup with your WiFi SSID as parameter. When prompted, enter your WiFi password.

The S20 device should reboot: the LED turns off, then blinks red, then shows a steady red (if everything worked fine). The whole sequence may take a minute.

Warning: if you have multiple S20 devices on the network, they will all be impacted. It is not guaranteed this will work, and some device might need to be reprogrammed. It is recommended to disconnect all other S20 devices when setting up one.

Warning: the WiFi password is sent in the clear, possibly through an open WiFi network.

147 changes: 147 additions & 0 deletions orvibosetup.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/* orvibosetup - A simple program to setup an Orvibo S20 wiFi plug.
*
* Copyright 2020, Pascal Martin
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*
* orvibosetup.c - Setup an Orvibo S20 WiFi plug or switch.
*
* SYNOPSYS:
*
* orvibosetup ssid
*
*/

#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>

static int OrviboSocket = -1;
static struct sockaddr_in OrviboBroadcast;

static void orvibo_socket (void) {

static int OrviboPort = 48899;

OrviboBroadcast.sin_family = AF_INET;
OrviboBroadcast.sin_port = htons(OrviboPort);
OrviboBroadcast.sin_addr.s_addr = INADDR_BROADCAST;

OrviboSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (OrviboSocket < 0) {
printf ("cannot open UDP socket: %s\n", strerror(errno));
exit(1);
}

int value = 1;
if (setsockopt(OrviboSocket, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value)) < 0) {
printf ("cannot broadcast: %s\n", strerror(errno));
exit(1);
}
printf ("UDP socket is ready.\n");
}

static unsigned char hex2bin(char data) {
if (data >= '0' && data <= '9')
return data - '0';
if (data >= 'a' && data <= 'f')
return data - 'a' + 10;
if (data >= 'A' && data <= 'F')
return data - 'A' + 10;
return 0;
}

static char bin2hex (unsigned char d) {
d &= 0x0f;
if (d >= 0 && d <= 9) return '0' + d;
if (d >= 10 && d <= 15) return ('a' - 10) + d;
return '0';
}

static void orvibo_send (const char *d, const char *private) {
struct sockaddr_in a;
int sent = sendto (OrviboSocket, d, strlen(d), 0,
(struct sockaddr *)(&OrviboBroadcast),
sizeof(struct sockaddr_in));
if (sent < 0) {
printf ("** sendto() error: %s", strerror(errno));
exit(1);
}
if (!private)
printf ("Sending %s\n", d);
else {
char privacy[256];
strncpy (privacy, d, sizeof(privacy));
char *p = strstr (privacy, private);
int i = strlen(private);
while (--i>=0) *(p++) = '*';
printf ("Sending %s\n", privacy);
}
}

static void orvibo_receive (void) {

char data[128];
struct sockaddr_in addr;
int addrlen = sizeof(addr);

int size = recvfrom (OrviboSocket, data, sizeof(data), 0,
(struct sockaddr *)(&addr), &addrlen);

if (size <= 0) {
printf ("** recvfrom() error: %s", strerror(errno));
return;
}
printf ("Received: %s\n", data);
}

int main (int argc, char **argv) {

char buffer[256];

if (argc != 2) {
fprintf (stderr, "Invalid parameters: need SSID.\n");
exit(1);
}
snprintf (buffer, sizeof(buffer), "WiFi password for %s? ", argv[1]);
char *password = strdup(getpass(buffer));

fflush(stdout);

orvibo_socket ();
orvibo_send ("HF-A11ASSISTHREAD", 0);
orvibo_receive();
orvibo_send ("+ok", 0);
snprintf (buffer, sizeof(buffer), "AT+WSSSID=%s\r", argv[1]);
orvibo_send (buffer, 0);
orvibo_receive();
snprintf (buffer, sizeof(buffer), "AT+WSKEY=WPA2PSK,AES,%s\r", password);
orvibo_send (buffer, password);
orvibo_receive();
orvibo_send ("AT+WMODE=STA\r", 0);
orvibo_receive();
orvibo_send ("AT+Z\r", 0);
return 0;
}

0 comments on commit 9649fdd

Please sign in to comment.