mbed RPC Server - Eclipse SmartHome Variante

Dependencies:   EthernetInterface HttpServer Motor Servo mbed-rtos mbed StepperMotorUni TMP175

Fork of RPCHTTPServerSimple by smd.iotkit2.ch

Das ist der mbed Teil zu Eclipse SmartHome (openHAB2). Compiliert das Programm und lädt es auf das Board.

Installation Eclipse SmartHome

Lädt eine vorbereitete Version des openHAB2 Runtimes von http://images.workshoptage.ch/images/ws4/ herunter und entpackt es auf Eurem PC. Alternativ kann die Entwicklungsumgebung von openHAB2 inkl. Eclipse wie hier beschrieben, installiert werden.

Zusätzlich ist das Addon (Eclipse Plug-In - ch.iotkit.smarthome.binding.mbedRPC*), ebenfalls von http://images.workshoptage.ch/images/ws4/ downzuladen und ins Verzeichnis addons zu kopieren.

Danach kann das openHAB2 Runtime mittels des start Datei gestartet werden und das UI mittels http://localhost:8080 aufrufen werden.

Der Sourcecode zum Eclipse Plug-In befindet sich auf GitHub

Konfiguration

Vorgehen:

  • Konfiguriert die Ethernet Bridge mit der IP Adresse des IoTKit SMD Shield
  • Fügt die Sensoren, Aktoren, LED's etc. vom IoTKit SMD Shield hinzu, aufbauend auf der Bridge

Unterstützte Geräte

  • Sensoren (auf Shield)
    • Poti (Pin A0)
    • Helligkeits Sensor (Pin A1)
    • Hall Sensor (Pin A2)
    • Temperatur Sensor (mittels I2C Bus)
  • Aktoren
    • Motor (Pin D3, D2, D4), verbinden mit DCMOT D2-D7 oben
    • Servo (Pin D9), verbinden mit Servo2 Stecker
    • Stepper (K64F Pins), verbinden mit STEPPER3, rotes Kabel nach unten
  • LED's (auf Shield)
    • LED's rot, gelb, grün, blau (Pin D10 - D13)
  • LED Strip 12 Volt (Pin D5 - D7), verbinden mit FET D5-D7, 12V oben

Der Motor und der LED Strip benötigen ein externes 12 Volt Netzteil.

cURL

Die Funktionen können mittels cURL oder Browser wie folgt getestet werden:

# RGB LED Strip (weiss 0xFFFFFF, rot 0xFF00, grün 0xFF0000, blau, 0xFF)
http://192.168.178.32/rpc/ledstrip/write+16777215
http://192.168.178.32/rpc/ledstrip/write+‭16711680‬
http://192.168.178.32/rpc/ledstrip/write+65280
http://192.168.178.32/rpc/ledstrip/write+255
 
# Motor Up, Down, Stop (Simulation Rollladen)
http://192.168.178.32/rpc/motor1/up
http://192.168.178.32/rpc/motor1/down
http://192.168.178.32/rpc/motor1/stop
 
# Schrittmotor                               
http://192.168.178.32/rpc/stepper1/up
http://192.168.178.32/rpc/stepper1/down
 
# Servo (Positionieren 0 - 1.0 und Position lesen)
http://192.168.178.32/rpc/servo1/write+0.5
http://192.168.178.32/rpc/servo1/read
 
# Temperatur Sensor abfragen                        
http://192.168.178.32/rpc/temp/read

IP-Adresse entsprechend dem Board anpassen.

Committer:
marcel1691
Date:
Fri Aug 28 12:33:30 2015 +0000
Revision:
16:d0a5bb230d94
Parent:
11:43e28c85fd75
Temp (I2C), RGB LED Strip impl.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
stefan1691 11:43e28c85fd75 1 /* mbed Microcontroller Library
stefan1691 11:43e28c85fd75 2 * Copyright (c) 2006-2013 ARM Limited
stefan1691 11:43e28c85fd75 3 *
stefan1691 11:43e28c85fd75 4 * Licensed under the Apache License, Version 2.0 (the "License");
stefan1691 11:43e28c85fd75 5 * you may not use this file except in compliance with the License.
stefan1691 11:43e28c85fd75 6 * You may obtain a copy of the License at
stefan1691 11:43e28c85fd75 7 *
stefan1691 11:43e28c85fd75 8 * http://www.apache.org/licenses/LICENSE-2.0
stefan1691 11:43e28c85fd75 9 *
stefan1691 11:43e28c85fd75 10 * Unless required by applicable law or agreed to in writing, software
stefan1691 11:43e28c85fd75 11 * distributed under the License is distributed on an "AS IS" BASIS,
stefan1691 11:43e28c85fd75 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
stefan1691 11:43e28c85fd75 13 * See the License for the specific language governing permissions and
stefan1691 11:43e28c85fd75 14 * limitations under the License.
stefan1691 11:43e28c85fd75 15 */
stefan1691 11:43e28c85fd75 16 #include "rpc.h"
stefan1691 11:43e28c85fd75 17
stefan1691 11:43e28c85fd75 18 using namespace std;
stefan1691 11:43e28c85fd75 19
stefan1691 11:43e28c85fd75 20 namespace mbed {
stefan1691 11:43e28c85fd75 21
stefan1691 11:43e28c85fd75 22 RPC::RPC(const char *name) {
stefan1691 11:43e28c85fd75 23 _from_construct = false;
stefan1691 11:43e28c85fd75 24 if (name != NULL) {
stefan1691 11:43e28c85fd75 25 _name = new char[strlen(name) + 1];
stefan1691 11:43e28c85fd75 26 strcpy(_name, name);
stefan1691 11:43e28c85fd75 27 } else {
stefan1691 11:43e28c85fd75 28 _name = new char[12];
stefan1691 11:43e28c85fd75 29 sprintf(_name, "obj%p", this);
stefan1691 11:43e28c85fd75 30 }
stefan1691 11:43e28c85fd75 31 // put this object at head of the list
stefan1691 11:43e28c85fd75 32 _next = _head;
stefan1691 11:43e28c85fd75 33 _head = this;
stefan1691 11:43e28c85fd75 34 }
stefan1691 11:43e28c85fd75 35
stefan1691 11:43e28c85fd75 36 RPC::~RPC() {
stefan1691 11:43e28c85fd75 37 // remove this object from the list
stefan1691 11:43e28c85fd75 38 if (_head == this) { // first in the list, so just drop me
stefan1691 11:43e28c85fd75 39 _head = _next;
stefan1691 11:43e28c85fd75 40 } else { // find the object before me, then drop me
stefan1691 11:43e28c85fd75 41 RPC* p = _head;
stefan1691 11:43e28c85fd75 42 while (p->_next != this) {
stefan1691 11:43e28c85fd75 43 p = p->_next;
stefan1691 11:43e28c85fd75 44 }
stefan1691 11:43e28c85fd75 45 p->_next = _next;
stefan1691 11:43e28c85fd75 46 }
stefan1691 11:43e28c85fd75 47 }
stefan1691 11:43e28c85fd75 48
stefan1691 11:43e28c85fd75 49 const rpc_method *RPC::get_rpc_methods() {
stefan1691 11:43e28c85fd75 50 static const rpc_method methods[] = {
stefan1691 11:43e28c85fd75 51 {"delete", rpc_method_caller<RPC, &RPC::delete_self> },
stefan1691 11:43e28c85fd75 52 RPC_METHOD_END
stefan1691 11:43e28c85fd75 53 };
stefan1691 11:43e28c85fd75 54 return methods;
stefan1691 11:43e28c85fd75 55 }
stefan1691 11:43e28c85fd75 56
stefan1691 11:43e28c85fd75 57 RPC *RPC::lookup(const char *name) {
stefan1691 11:43e28c85fd75 58 size_t len = strlen(name);
stefan1691 11:43e28c85fd75 59 for (RPC *p = _head; p != NULL; p = p->_next) {
stefan1691 11:43e28c85fd75 60 /* Check that p->_name matches name and is the correct length */
stefan1691 11:43e28c85fd75 61 if (strncmp(p->_name, name, len) == 0 && (strlen(p->_name) == len)) {
stefan1691 11:43e28c85fd75 62 return p;
stefan1691 11:43e28c85fd75 63 }
stefan1691 11:43e28c85fd75 64 }
stefan1691 11:43e28c85fd75 65 return NULL;
stefan1691 11:43e28c85fd75 66 }
stefan1691 11:43e28c85fd75 67
stefan1691 11:43e28c85fd75 68 void RPC::delete_self() {
stefan1691 11:43e28c85fd75 69 delete[] _name;
stefan1691 11:43e28c85fd75 70 if (_from_construct) {
stefan1691 11:43e28c85fd75 71 delete this;
stefan1691 11:43e28c85fd75 72 }
stefan1691 11:43e28c85fd75 73 }
stefan1691 11:43e28c85fd75 74
stefan1691 11:43e28c85fd75 75 void RPC::list_objs(Arguments *args, Reply *result) {
stefan1691 11:43e28c85fd75 76 for (RPC *ptr = RPC::_head; ptr != NULL; ptr = ptr->_next) {
stefan1691 11:43e28c85fd75 77 if (ptr->_from_construct) {
stefan1691 11:43e28c85fd75 78 result->putData<const char*>(ptr->_name);
stefan1691 11:43e28c85fd75 79 }
stefan1691 11:43e28c85fd75 80 }
stefan1691 11:43e28c85fd75 81 }
stefan1691 11:43e28c85fd75 82
stefan1691 11:43e28c85fd75 83 void RPC::clear(Arguments*, Reply*) {
stefan1691 11:43e28c85fd75 84 RPC *ptr = RPC::_head;
stefan1691 11:43e28c85fd75 85 while (ptr != NULL) {
stefan1691 11:43e28c85fd75 86 RPC *tmp = ptr;
stefan1691 11:43e28c85fd75 87 ptr = ptr->_next;
stefan1691 11:43e28c85fd75 88 delete[] tmp->_name;
stefan1691 11:43e28c85fd75 89 if (tmp->_from_construct) {
stefan1691 11:43e28c85fd75 90 delete tmp;
stefan1691 11:43e28c85fd75 91 }
stefan1691 11:43e28c85fd75 92 }
stefan1691 11:43e28c85fd75 93 }
stefan1691 11:43e28c85fd75 94
stefan1691 11:43e28c85fd75 95 const rpc_function RPC::_RPC_funcs[] = {
stefan1691 11:43e28c85fd75 96 {"clear", &RPC::clear },
stefan1691 11:43e28c85fd75 97 { "objects", &RPC::list_objs },
stefan1691 11:43e28c85fd75 98 RPC_METHOD_END
stefan1691 11:43e28c85fd75 99 };
stefan1691 11:43e28c85fd75 100
stefan1691 11:43e28c85fd75 101 rpc_class RPC::_RPC_class = { "RPC", _RPC_funcs, NULL };
stefan1691 11:43e28c85fd75 102
stefan1691 11:43e28c85fd75 103 RPC *RPC::_head = NULL;
stefan1691 11:43e28c85fd75 104
stefan1691 11:43e28c85fd75 105 rpc_class *RPC::_classes = &_RPC_class;
stefan1691 11:43e28c85fd75 106
stefan1691 11:43e28c85fd75 107 bool RPC::call(const char *request, char *reply) {
stefan1691 11:43e28c85fd75 108 if (request == NULL) return false;
stefan1691 11:43e28c85fd75 109
stefan1691 11:43e28c85fd75 110 Arguments args(request);
stefan1691 11:43e28c85fd75 111 Reply r(reply);
stefan1691 11:43e28c85fd75 112
stefan1691 11:43e28c85fd75 113 /* If there's no name print object and class names to result */
stefan1691 11:43e28c85fd75 114 if (args.obj_name == NULL) {
stefan1691 11:43e28c85fd75 115 for (RPC *p = RPC::_head; p != NULL; p = p->_next) {
stefan1691 11:43e28c85fd75 116 r.putData<const char*>(p->_name);
stefan1691 11:43e28c85fd75 117 }
stefan1691 11:43e28c85fd75 118 for (rpc_class *c = RPC::_classes; c != NULL; c = c->next) {
stefan1691 11:43e28c85fd75 119 r.putData<const char*>(c->name);
stefan1691 11:43e28c85fd75 120 }
stefan1691 11:43e28c85fd75 121 return true;
stefan1691 11:43e28c85fd75 122 }
stefan1691 11:43e28c85fd75 123
stefan1691 11:43e28c85fd75 124 /* First try matching an instance */
stefan1691 11:43e28c85fd75 125 RPC *p = lookup(args.obj_name);
stefan1691 11:43e28c85fd75 126 if (p != NULL) {
stefan1691 11:43e28c85fd75 127 /* Get the list of methods we support */
stefan1691 11:43e28c85fd75 128 const rpc_method *cur_method = p->get_rpc_methods();
stefan1691 11:43e28c85fd75 129
stefan1691 11:43e28c85fd75 130 /* When there's no method print method names to result */
stefan1691 11:43e28c85fd75 131 if (args.method_name == NULL) {
stefan1691 11:43e28c85fd75 132 while (true) {
stefan1691 11:43e28c85fd75 133 for (; cur_method->name != NULL; cur_method++) {
stefan1691 11:43e28c85fd75 134 r.putData<const char*>(cur_method->name);
stefan1691 11:43e28c85fd75 135 }
stefan1691 11:43e28c85fd75 136
stefan1691 11:43e28c85fd75 137 /* write_name_arr's args are references, so result and cur_method will have changed */
stefan1691 11:43e28c85fd75 138 if (cur_method->super != 0) {
stefan1691 11:43e28c85fd75 139 cur_method = cur_method->super(p);
stefan1691 11:43e28c85fd75 140 } else {
stefan1691 11:43e28c85fd75 141 return true;
stefan1691 11:43e28c85fd75 142 }
stefan1691 11:43e28c85fd75 143 }
stefan1691 11:43e28c85fd75 144 }
stefan1691 11:43e28c85fd75 145
stefan1691 11:43e28c85fd75 146 /* Look through the methods for the one whose name matches */
stefan1691 11:43e28c85fd75 147 while (true) {
stefan1691 11:43e28c85fd75 148 for (; cur_method->name != NULL; cur_method++) {
stefan1691 11:43e28c85fd75 149 if (strcmp(cur_method->name, args.method_name) == 0) {
stefan1691 11:43e28c85fd75 150 (cur_method->method_caller)(p, &args, &r);
stefan1691 11:43e28c85fd75 151 return true;
stefan1691 11:43e28c85fd75 152 }
stefan1691 11:43e28c85fd75 153 }
stefan1691 11:43e28c85fd75 154
stefan1691 11:43e28c85fd75 155 if (cur_method->super != 0) {
stefan1691 11:43e28c85fd75 156 cur_method = cur_method->super(p);
stefan1691 11:43e28c85fd75 157 } else {
stefan1691 11:43e28c85fd75 158 /* end of methods and no match */
stefan1691 11:43e28c85fd75 159 return false;
stefan1691 11:43e28c85fd75 160 }
stefan1691 11:43e28c85fd75 161
stefan1691 11:43e28c85fd75 162 }
stefan1691 11:43e28c85fd75 163 }
stefan1691 11:43e28c85fd75 164
stefan1691 11:43e28c85fd75 165 /* Then try a class */
stefan1691 11:43e28c85fd75 166 for (const rpc_class *q = _classes; q != NULL; q = q->next) {
stefan1691 11:43e28c85fd75 167 if (strcmp(q->name, args.obj_name) == 0) {
stefan1691 11:43e28c85fd75 168 /* Matched the class name, so get its functions */
stefan1691 11:43e28c85fd75 169 const rpc_function *cur_func = q->static_functions;
stefan1691 11:43e28c85fd75 170 if (args.method_name == NULL) {
stefan1691 11:43e28c85fd75 171 for (; cur_func->name != NULL; cur_func++) {
stefan1691 11:43e28c85fd75 172 r.putData<const char*>(cur_func->name);
stefan1691 11:43e28c85fd75 173 }
stefan1691 11:43e28c85fd75 174 return true;
stefan1691 11:43e28c85fd75 175 } else {
stefan1691 11:43e28c85fd75 176 /* Otherwise call the appropriate function */
stefan1691 11:43e28c85fd75 177 for (; cur_func->name != NULL; cur_func++) {
stefan1691 11:43e28c85fd75 178 if (strcmp(cur_func->name, args.method_name) == 0) {
stefan1691 11:43e28c85fd75 179 (cur_func->function_caller)(&args, &r);
stefan1691 11:43e28c85fd75 180 return true;
stefan1691 11:43e28c85fd75 181 }
stefan1691 11:43e28c85fd75 182 }
stefan1691 11:43e28c85fd75 183 return false;
stefan1691 11:43e28c85fd75 184 }
stefan1691 11:43e28c85fd75 185 }
stefan1691 11:43e28c85fd75 186 }
stefan1691 11:43e28c85fd75 187
stefan1691 11:43e28c85fd75 188 return false;
stefan1691 11:43e28c85fd75 189 }
stefan1691 11:43e28c85fd75 190
stefan1691 11:43e28c85fd75 191 } // namespace mbed