Nous contrôlons l'éclairage de l'appartement (NooLite, Raspberry Pi et WebIOPi)

Je veux partager l'expérience de l'utilisation du système de maison intelligente NooLite avec le Raspberry Pi Model B (ci-après RPI ) dans un appartement de deux pièces.
À propos du système NooLite ont été écrits à plusieurs reprises sur un concentrateur:

Dans cet article, je dirai:



  • ( ): RPI + WebIOPi (UART+REST) + NooLite
  • : NooLite —
  • ( , ): Android, WEB-, bash shell (python script)

Peut-être que quelqu'un pensera: «Je ne m'embêterais pas avec RPI pour des fonctionnalités aussi simples - pour contrôler l'éclairage dans l'appartement à partir d'un téléphone mobile, mais je réaliserais tout en utilisant une tasse en plastique, un caillou et un fil sur un Arduino avec un bouclier Wi-Fi ou un simple. implémentation concise sur le microcontrôleur AVR. "
Mais, comme je ramassais déjà de la poussière sur l'étagère RPI et que le désir de créer un éclairage «intelligent» à l'aide de la plate-forme RPI, j'étais décidé à le prendre comme base. De plus, la possibilité d'utiliser RPI offre une bonne marge pour étendre les fonctionnalités de la «maison intelligente».

Des données d'entrée


  • Appartement 2 pièces P44T sans réparation dans un immeuble neuf
  • RPI (acquis il y a deux ans pour des raisons d'intérêt)
  • désir de réaliser un éclairage intelligent

Pendant un certain temps, je me suis penché sur différentes plates-formes et technologies de la maison intelligente.Par conséquent, le choix s'est porté sur le système NooLite, sur la base des éléments suivants:
  • prix adéquat par rapport à des systèmes similaires (Z-Wave, EnOcean, ZigBee)
  • Je fais confiance aux produits fabriqués au Bélarus
  • protocole ouvert
  • de nombreux exemples d'utilisation sur Internet
  • 433 MHz répandu et ratifié par le SCRF

J'ai également attiré l'attention sur la plate-forme Wiren Board basée sur ARM9 pour la domotique avec des fonctionnalités riches pour tous les besoins imaginables et inimaginables. J'ai été particulièrement satisfait de la fonctionnalité de tueur - un module radio 433 MHz, qui dans mon cas est adapté pour contrôler les unités d'alimentation NooLite. Mais comme j'ai déjà un RPI, nous allons continuer sur cette lancée.
Pour mettre en place un éclairage «intelligent» dans l'appartement, je devais résoudre les tâches suivantes:
  1. déterminer le scénario d'éclairage optimal dans un appartement de deux pièces
  2. définir une méthode d'intégration avec RPI et de placement à faible courant
  3. choisissez un wrapper à contrôler
  4. faire une liste de courses
  5. coordonner ce qui précède avec sa femme
  6. acheter les composants nécessaires
  7. lier des télécommandes et déboguer l'intégration RPI> NooLite
  8. trouver et acheter des interrupteurs appropriés pour les télécommandes
  9. placer des blocs d'alimentation et des interrupteurs
  10. développer une application mobile pour Android

Les éléments 1 et 4-6 peuvent être répétés dans un cycle.
Prix ​​d'émission:
  • RPI [1 pièce]
  • Module NooLite MT1132 [1 140 ₽ X 1 pc] 1 140 ₽
  • Blocs d'alimentation NL [1 240 ₽ X 11 pièces] 13 640 ₽
  • Panneaux de commande fixes NL [1 340 ₽ X 7 pièces] 9 380 ₽
  • Porte-clés télécommande NL [1 550 ₽ X 1 pc] 1 550 ₽
  • Détecteur de mouvement NL [1 550 ₽ X 1 pc] 1 550 ₽
  • Boîtes de montage, supports, modules clavier / bouton (commutateurs), cadres (achetés individuellement)
  • amis avec une imprimante 3D - gratuitement

Total: ~ 27 000 ₽ + contrôleur à partir de 3 000 ₽.

Scénario d'éclairage d'appartement


La disposition du gilet d'angle deux pièces P44T avec une baie vitrée est donnée ci-dessous.

Il est prévu de contrôler l'éclairage avec NooLite dans toutes les pièces sauf la loggia, la salle de bain et les toilettes.
Le couloir

2 points d'éclairage avec mode relais (marche / arrêt).
Un point lumineux moins brillant doit être contrôlé par le capteur de mouvement PM111 . Cela permettra dans l'obscurité d'éclairer le chemin du vagabond de nuit à la recherche des lumières de la faim nocturne.

Les deux points d'éclairage doivent être contrôlés par un interrupteur fixe situé à côté de la porte d'entrée. L'interrupteur doit inclure le scénario «éteindre les lumières dans tout l'appartement».
Le capteur de mouvement thermique passe en mode veille (commence à répondre au mouvement des objets thermiques) lorsque vous définissez le niveau d'éclairage et la sensibilité requis de la pièce. Habituellement pendant la journée, il n'est pas nécessaire de faire clignoter la lumière dans le couloir pour passer.
D'après les instructions du capteur:
Si l'éclairage près du capteur PM111 est supérieur à celui défini par le régulateur d'éclairage, le capteur est en mode veille. Dans le même temps, sa consommation de courant est minime (moins de 1 μA) et le capteur de mouvement thermique est désactivé. Lorsque l'éclairage tombe en dessous d'un niveau prédéterminé, le capteur passe en mode veille.

Les lumières dans les toilettes et la salle de bain sont contrôlées par un interrupteur fixe classique. La lumière et le ventilateur dans les toilettes sont connectés via un relais temporisé F&F PO-415 (également biélorusses) sur un rail DIN.

Du fait de la fermeture du contact de commande 6, les contacts de relais 11, 12 sont fermés. L'ouverture du contact de commande 6 provoque un compte à rebours du temps réglé, après quoi le fonctionnement du PO-415 s'arrête.

Le commutateur de corridor fixe doit être de type bouton-poussoir, car l'invocation d'un script implique d'appuyer sur un bouton (le script n'a pas d'états ON / OFF).
En outre, le bouton est nécessaire si nous devons éteindre la lumière déjà allumée par le capteur de mouvement, lorsque la minuterie du capteur est configurée pour ne pas éteindre la lumière pendant plusieurs minutes après avoir été déclenchée. La clé ne rentre pas dans ce cas.
Total dans le couloir:
  • deux unités de puissance de type relais 200 W ( SU111-200 en mode relais)
  • un interrupteur à 3 boutons fixe (télécommande PK313 ):
    • Bouton 1 - éclairage marche / arrêt du point lumineux 1
    • bouton 2 - allumer / éteindre l'éclairage du point lumineux 2
    • bouton 3 - éteindre la lumière dans tout l'appartement (script)



Cuisine

Trois points d'éclairage:
  • lampe au dessus de la table ( mode relais SU111-200 )
  • éclairage spot en plafond tendu ( mode relais SU111-200 )
  • Bande LED pour éclairer la surface de travail de la cuisine ( mode relais SU111-200 )

Les points d'éclairage sont contrôlés par un interrupteur à 3 boutons (télécommande PK311 ) situé à l'entrée de la cuisine.

Séjour et balcon

Deux points d'éclairage en mode relais ( SU111-200 ):
  • éclairage principal dans le salon
  • lumière sur le balcon

Chaque point d'éclairage est contrôlé par 2 interrupteurs:
  • Interrupteur fixe à 2 boutons sur le balcon (télécommande PK313 ):
    • Bouton 1 - lumière marche / arrêt sur le balcon
    • bouton 2 - allumer / éteindre la lumière dans le salon

  • Interrupteur fixe à 2 touches dans le salon ( PK314 Remote ):
    • touche 1 - allumer / éteindre la lumière dans le salon
    • touche 2 - lumière allumée / éteinte sur le balcon



Peut-être que quelqu'un demandera "pourquoi ne pas mettre un interrupteur à 2 touches sur le balcon comme dans le salon?" ou "pourquoi ne pas mettre des boutons dans tout l'appartement?".
Il en est ainsi, au début, il était censé installer un interrupteur à 3 boutons avec un bouton de scénario sur le balcon, mais a ensuite changé d'avis lors du choix de la conception des interrupteurs eux-mêmes. On a également supposé qu'il y aurait des boutons dans le couloir et dans la cuisine, et des interrupteurs à clé dans le salon, la chambre et le balcon pour préserver le design.
Plus tard, j'ai voulu atténuer la lumière avec un interrupteur près du lit, donc tout s'est mal passé. Pour préserver la conception des disjoncteurs, j'ai dû parcourir de nombreux marchés de la construction, visiter une dizaine de sites Internet, plus à ce sujet plus loin dans la section « Trouver et acheter des disjoncteurs adaptés aux télécommandes ».
Chambre

Section 1 (lit)
Habituellement, des blocs d'alimentation sont situés à chaque point d'éclairage. Un point d'éclairage - une unité d'alimentation. Dans mon scénario d'éclairage, il y a un écart par rapport à la logique traditionnelle. Dans la chambre «section 1», il est censé installer une lampe avec deux blocs d'alimentation, dont l'un sera atténué.
Section 2 (baie vitrée)
En plus des interrupteurs fixes, tous les points d'éclairage doivent être contrôlés à partir d'une télécommande de poche comme console de secours et RPI. Pour le trousseau:
  • bouton A (allumer / éteindre la lumière dans le couloir et dans la cuisine)
  • bouton B (allumer / éteindre la lumière dans le salon et sur le balcon)
  • bouton C (allumer / éteindre la lumière dans la chambre)


Définition du placement à faible courant et de la méthode d'intégration NooLite C pour RPI


Je dirai tout de suite, l'intégration est simple. NooLite possède un module MT1132 . Le module reçoit un paquet de contrôle via UART de certains contrôleurs, dans mon cas, c'est un RPI, transmet une commande par voie aérienne aux appareils exécutifs (blocs d'alimentation) et répond avec la construction OK / r \ n, tout est décrit dans les instructions du module .
Tension d'alimentation du module (VCC Upit)2,7-5,5 V
plage de tension d'entrée à Rx0 - Haut
TTL HIGH LVL (unité logique) à Upit = 5 V2 - Upit (5 V)
TTL LOW LVL (zéro logique) à Upit = 5 V0-0,8 V
TTL HIGH LVL (unité logique) à Upit = 3,3 V2-3,3 V
TTL LOW LVL (zéro logique) à Upit = 3,3 V0-0,8 V
Vitesse UART9600 bauds


Étant donné que les lignes RPART UART fonctionnent avec des niveaux TTL de 3,3 V, nous utiliserons 3,3 V comme puissance U du module.

Vous pouvez utiliser trois lignes sur le MT1132: VCC, GND et RX pour transmettre un paquet de contrôle. Je l'ai fait lors du débogage - je n'ai pas lu la réponse "OK \ r \ n" de MT1132, il m'a suffi d'observer l'indicateur de l'unité d'alimentation connectée. Lors de l'acceptation réussie de la commande de «liaison», un clignotement fréquent de la LED intégrée est initié sur le bloc d'alimentation.
Autre point, la puissance de l'émetteur radio avec une puissance U de 3,3 V à 3,3 mW, avec une puissance U de 5 V à 5 mW. La distance maximale à l'unité de puissance est de 70 m.

À propos du package de contrôle


Le paquet de contrôle se compose de 12 octets:
ST, B0, B1, B2, B3, B4, B5, B6, B7, B8, CS, SP
ST - octet de démarrage, toujours 85
B0..B8 - charge utile (commandes de contrôle)
CS - vérifier la somme. L'octet le moins significatif de la somme des 10 premiers octets (ST à B8)
SP - octet d'arrêt
Selon les instructions, j'ai écrit les octets de contrôle dont j'ai besoin:
B1 - commande de contrôle avec des valeurs:
  • 0 - éteignez la charge
  • 2 - allumez la charge
  • 4 - allumer ou éteindre la charge
  • 9 - découplage (démarrer le processus d'effacement de l'adresse de la mémoire du bloc d'alimentation)
  • 15 - liaison (enregistrer l'adresse du module dans le bloc d'alimentation)

B4 - adresse de canal (de 0 à 31). Seulement 32 canaux.
autres octets par défaut à l'exception de la somme de contrôle.
B0 - réglage du mode de transmission du module.
Si la valeur 80 (0x50) est passée à B0, alors:
  • nombre de répétitions - 2
  • bitrate 2-1000 bps
  • mode 0 - envoyer une commande


En conséquence, j'ai compilé une telle table avec les packages de contrôle nécessaires pour moi.
Placement dans le panneau électrique

Il a été décidé d'installer un courant faible dans le tableau interne:
  • Le RPI est monté sur un rail DIN en attachant des amis imprimés sur une imprimante 3D
  • Module MT1132 pour contrôler les unités de puissance par voie aérienne
  • deux ~ 220 prises sur DIN pour la connexion des blocs d'alimentation d'un routeur et RPI


Débogage d'intégration et sélection de wrappers pour la gestion


Conditions préalables:
  • RPI
  • Module MT1132
  • fils mère à mère pour connecter les broches MT1132 et RPI GPIO
  • Carte SD avec n'importe quelle image RPI préinstallée
  • accès à la console RPI SHELL (bash, csh, korn, etc.) (clavier direct ou distant via SSH)
  • packages de contrôle préparés
  • bibliothèque pour travailler avec UART via l'en-tête GPIO dans RPI

Lors de la préparation de l'image, j'ai attrapé un bogue câblé cool sur le Macbook Air lors de l'enregistrement de l'image Raspbian-wheezy sous la racine (bien que pour moi, c'est une fonctionnalité - protection supplémentaire en écriture, détrompez-vous avant d'écraser les données):
dd bs=1m if=2015-02-16-raspbian-wheezy.img of=/dev/disk2

La console a renvoyé:
dd: /dev/disk2: Permission denied 

Avec le verrou retiré sur la carte SD, sous la racine et les bons mods sur / dev / disk2 ....
Ensuite, j'ai trouvé un métier sur ce sujet , quelqu'un a aidé à souffler dans la fente SD sur le coquelicot, quelqu'un a eu une machine à sous. Battre un macbook est un gaspillage aujourd'hui, et en conséquence, un petit écart m'a aidé: si la carte SD n'est pas complètement insérée, tout fonctionnera.
Pendant le débogage, j'ai dû faire une ferme collective, car il n'y avait pas de connecteurs mère-mère adaptés.

Étant donné que j'avais besoin d'un wrapper pour contrôler les unités d'alimentation via WEB, la possibilité de faire des demandes REST à l'avenir et une bibliothèque UART à partir d'une seule boîte - le choix s'est porté sur WebIOPi .

Bien que je veuille construire OpenHAB à cause de l'architecture cool. La plateforme d'automatisation a été décrite sur Habré .
J'utiliserai certainement cette plate-forme à l'avenir, mais pour l'instant, pour ma «liste de souhaits», la plate-forme choisie est suffisante.
Architecture d'interaction générale


Configuration minimale de WebIOPi
En utilisant les instructions fournies sur le site Web du projet:
  1. installer le framework WebIOPi en suivant ces étapes
    • Installation
    • Exécution de WebIOPi (démon)
    • Démarrage automatique au démarrage

  2. configurer UART en modifiant 3 fichiers: / etc / inittab, /boot/cmdline.txt, / etc / webiopi / config. Pas:
    • Uart à bord
    • Configuration de WebIOPi

  3. nous reproduisons les actions décrites dans la section
    • Astuce Serial Loopback (envoyez-nous la «chaîne» via UART et lisez l'interface WEBIOPi dans la section Serial Monitor)
    • la vidéo dans la section Serial Monitor affiche le processus



Installez un cavalier pour tester la boucle UART.
En utilisant la table précédemment compilée avec les packages de contrôle, nous allons écrire un simple script Python pour gérer le module à partir de RPI SHELL.
Script RPI Shell pour le module MT1132
#!/usr/bin/python
import sys, getopt
def main(argv):
   ch = ''
   cmd = ''
   try:
      opts, args = getopt.getopt(argv,"h:",["ch=","cmd="])
   except getopt.GetoptError:
      print 'mt1132.py --ch <channel_number> --cmd <ON/OFF/BIND/UNBIND>'
      sys.exit(2)
   for opt, arg in opts:
      if opt == '-h':
         print 'mt1132.py --ch <channel_number> --cmd <ON/OFF/BIND/UNBIND>'
         sys.exit()
      elif opt in ("--ch"):
         ch = arg
      elif opt in ("--cmd"):
         cmd = arg
   print 'Channel: ', ch
   print 'Command: ', cmd
   if cmd=='ON' and ch!='':
        if ch=='0':
                print 'Switch ON channel 0'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00a7, 0x00aa])
        elif ch=='1':
                print 'Switch ON channel 1'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00a8, 0x00aa])
        elif ch=='2':
                print 'Switch ON channel 2'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00a9, 0x00aa])
        elif ch=='3':
                print 'Switch ON channel 3'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00aa, 0x00aa])
        elif ch=='4':
                print 'Switch ON channel 4'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00ab, 0x00aa])
        elif ch=='5':
                print 'Switch ON channel 5'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00ac, 0x00aa])
        elif ch=='6':
                print 'Switch ON channel 6'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00ad, 0x00aa])
        elif ch=='7':
                print 'Switch ON channel 7'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00ae, 0x00aa])
        elif ch=='8':
                print 'Switch ON channel 8'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00af, 0x00aa])
        elif ch=='9':
                print 'Switch ON channel 9'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00b0, 0x00aa])
        elif ch=='10':
                print 'Switch ON channel 10'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00b1, 0x00aa])
   if cmd=='OFF' and ch!='':
        if ch=='0':
                print 'Switch OFF channel 0'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00a5, 0x00aa])
        elif ch=='1':
                print 'Switch OFF channel 1'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00a6, 0x00aa])
        elif ch=='2':
                print 'Switch OFF channel 2'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00a7, 0x00aa])
        elif ch=='3':
                print 'Switch OFF channel 3'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00a8, 0x00aa])
        elif ch=='4':
                print 'Switch OFF channel 4'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00a9, 0x00aa])
        elif ch=='5':
                print 'Switch OFF channel 5'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00aa, 0x00aa])
        elif ch=='6':
                print 'Switch OFF channel 6'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00ab, 0x00aa])
        elif ch=='7':
                print 'Switch OFF channel 7'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00ac, 0x00aa])
        elif ch=='8':
                print 'Switch OFF channel 8'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00ad, 0x00aa])
        elif ch=='9':
                print 'Switch OFF channel 9'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00ae, 0x00aa])
        elif ch=='10':
                print 'Switch OFF channel 10'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00ae, 0x00aa])
   if cmd=='BIND' and ch!='':
        if ch=='0':
                print 'BIND channel 0'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00b4, 0x00aa])
        elif ch=='1':
                print 'BIND channel 1'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00b5, 0x00aa])
        elif ch=='2':
                print 'BIND channel 2'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00b6, 0x00aa])
        elif ch=='3':
                print 'BIND channel 3'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00b7, 0x00aa])
        elif ch=='4':
                print 'BIND channel 4'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00b8, 0x00aa])
        elif ch=='5':
                print 'BIND channel 5'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00b9, 0x00aa])
        elif ch=='6':
                print 'BIND channel 6'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00ba, 0x00aa])
        elif ch=='7':
                print 'BIND channel 7'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00bb, 0x00aa])
        elif ch=='8':
                print 'BIND channel 8'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00bc, 0x00aa])
        elif ch=='9':
                print 'BIND channel 9'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00bd, 0x00aa])
        elif ch=='10':
                print 'BIND channel 10'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00be, 0x00aa])
   if cmd=='UNBIND' and ch!='':
        if ch=='0':
                print 'UNBIND channel 0'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00ae, 0x00aa])
        elif ch=='1':
                print 'UNBIND channel 1'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00af, 0x00aa])
        elif ch=='2':
                print 'UNBIND channel 2'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00b0, 0x00aa])
        elif ch=='3':
                print 'UNBIND channel 3'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00b1, 0x00aa])
        elif ch=='4':
                print 'UNBIND channel 4'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00b2, 0x00aa])
        elif ch=='5':
                print 'UNBIND channel 5'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00b3, 0x00aa])
        elif ch=='6':
                print 'UNBIND channel 6'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00b4, 0x00aa])
        elif ch=='7':
                print 'UNBIND channel 7'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00b5, 0x00aa])
        elif ch=='8':
                print 'UNBIND channel 8'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00b6, 0x00aa])
        elif ch=='9':
                print 'UNBIND channel 9'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00b7, 0x00aa])
        elif ch=='10':
                print 'UNBIND channel 10'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00b8, 0x00aa])
if __name__ == "__main__":
   main(sys.argv[1:])


Pour contrôler MT1132 à partir de la console shell, exécutez les commandes suivantes

mt1132.py --ch <channel_number> --cmd <ON/OFF/BIND/UNBIND>

Nous fixons l'API REST
Le framework WebIOPi fournit un contrôle via des requêtes HTTP dans le style REST , ce qui facilite la fixation des clients mobiles et simplifie l'interaction client-serveur.
Copiez-collez le framework API REST en utilisant le lien ci-dessus:
  • Obtenez la fonction GPIO
  • Définir la fonction GPIO
  • Obtenez la valeur GPIO
  • Définir la valeur GPIO
  • Sortie d'une seule impulsion
  • Séquence de bits de sortie
  • PWM de sortie avec un rapport cyclique
  • PWM de sortie avec un angle pour les servos
  • Appeler une macro sur le serveur
  • Obtenir l'état / la configuration GPIO complète

Notre cas est "Appeler une macro sur le serveur". La description n'est pas grasse, mais suffisante pour l'expérience:
HTTP POST / macros / (macro) / (args)
  • Renvoie la valeur renvoyée par la macro

Puisque (macro) n'a pas encore été préparée, nous allons vérifier le REST "Get full GPIO state / configuration", et pour cela nous devons faire une requête HTTP GET / *.
Nous ouvrons n'importe quel client API REST, j'ai utilisé le client DHC pour le navigateur Chrome. Nous essayons d'effectuer une requête REST pour obtenir l'heure actuelle.

Configuration WebIOPi (/ etc / webiopi / config)

Dans la section [DEVICES] :
Ajoutez un périphérique série (UART GPIO) - c'est notre module MT1132, où
ttyAMA0 est le périphérique (port) que le noyau Raspbian voit, le
débit en bauds est la vitesse en Échange d'informations en bauds via cette interface UART.
9600 bauds / (8 + 1 bit de démarrage + 1 bit d'arrêt) = 960 octets / s.
Dans la section [SCRIPTS] (scripts personnalisés):
Ajoutez la chaîne myscrypt = /home/pi/smarthome/python/mt1132.py - pour connecter notre script au framework.
Dans la section [REST] (paramètres de contrôle GPIO via l'API REST. Facultatif):
gpio-post-value = false - interdit de modifier les niveaux logiques BAS / HAUT sur les broches GPIO via les requêtes REST;
gpio-post-function = false - interdit de modifier le paramètre IN / OUT sur les broches GPIO via des requêtes REST.
Les paramètres restants restent inchangés.
[COAP] :
Je n'ai pas touché, déconnecté. Bien que je ne sache pas avec quoi il est mangé et où il est utilisé. J'ai enregistré uniquement cette ligne dans ma tête: oAP - est un protocole de transfert Web spécialisé à utiliser avec des nœuds et des réseaux contraints dans leInternet des objets , conçu pour les applications de machine à machine (M2M) telles que l'énergie intelligente et l'automatisation des bâtiments. "
Peut-être que sur Habr quelqu'un ouvre des cas utiles d'utilisation.
Ajoutez des macros pour les demandes REST à un script préalablement préparé.
# Channel 0	
@webiopi.macro	
def ch0(cmd):
	if cmd=='on':
		serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00a7, 0x00aa])
		webiopi.sleep(1)
		resp = 'Channel: 0, Cmd: ' + cmd + ', Status: ' + serial.readString()
	if cmd=='off':
		serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00a5, 0x00aa])
		webiopi.sleep(1)
		resp = 'Channel: 0, Cmd: ' + cmd + ', Status: ' + serial.readString()
	if cmd=='unbind':
		serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00ae, 0x00aa])
		webiopi.sleep(1)
		resp = 'Channel: 0, Cmd: ' + cmd + ', Status: ' + serial.readString()
	if cmd=='bind':
		serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00b4, 0x00aa])
		webiopi.sleep(1)
		resp = 'Channel: 0, Cmd: ' + cmd + ', Status: ' + serial.readString()
	return resp 


Test des demandes REST avec des macros

Nous envoyons une demande REST pour "lier l'adresse du 3ème canal NooLite MT1132 au bloc d'alimentation sur lequel la liaison est initiée" via DHC.
Si le paquet de contrôle est envoyé avec succès, le module MT1132 répondra via UART TX au GPIO UART RX «OK». En cas de succès, l'unité d'alimentation se souviendra de l'adresse du canal et clignotera intensément avec la LED verte intégrée.

Client simple pour Android


Au départ, je n'avais pas prévu d'écrire une application pour Android, du fait que je n'en avais aucune idée, je comptais me limiter à un navigateur. Puis il a accidentellement erré dans la chaîne Start Android . L'auteur, Dmitry, raconte en détail avec Andryukha comment démarrer rapidement son premier projet sous la plateforme Androyd. Un grand merci à l'auteur pour le projet et le travail acharné!
Après avoir regardé et terminé pas plus de vingt leçons, j'ai commencé à créer ma simple application de contrôle d'éclairage. Pour le développement, j'ai utilisé IDE Android Studio, comme le demande Google - basé sur IntelliJ IDEA.
Interface Le
résultat a été une interface très ascétique:

main.xml TEL QUEL
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@color/hl7"
    android:padding="2dp"
    android:clickable="false">

    <!-- -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal">
        <TextView
            android:id="@+id/r1c1"
            android:textSize="18sp"
            android:layout_width="110dp"
            android:layout_height="match_parent"
            android:padding="4dp"
            android:layout_margin="1dp"
            android:text=""
            android:background="@color/hl4"
            android:layout_weight="1"
            android:gravity="center"
            android:textColor="@color/white" />
        <TextView
            android:textColor="@color/white"
            android:textSize="18sp"
            android:id="@+id/r1c2"
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:padding="4dp"
            android:text=" "
            android:layout_margin="1dp"
            android:background="@color/hl4"
            android:layout_weight="2"
            android:gravity="center"/>
        <TextView
            android:textColor="@color/white"
            android:textSize="18sp"
            android:id="@+id/r1c3"
            android:layout_width="150dp"
            android:layout_height="match_parent"
            android:padding="4dp"
            android:text=""
            android:layout_margin="1dp"
            android:background="@color/hl4"
            android:layout_weight="3"
            android:gravity="center"/>
    </LinearLayout>

    <!--  -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:layout_width="110dp"
            android:layout_height="match_parent"
            android:textColor="@color/black"
            android:textSize="16sp"
            android:text="@string/room1txt"
            android:id="@+id/room1"
            android:layout_weight="1"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:gravity="center"
            android:background="@color/holotheme_color"
            android:textStyle="bold" />
        <LinearLayout
            android:orientation="vertical"
            android:background="@color/hl8"
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            android:layout_margin="1dp"
            android:gravity="center|top">
            <TextView
                android:layout_width="match_parent"
                android:textColor="@color/hl9"
                android:layout_height="36dp"
                android:text="@string/place1txt"
                android:id="@+id/r1switch1"
                android:textSize="13sp"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
            <TextView
                android:textSize="13sp"
                android:layout_width="match_parent"
                android:layout_height="36dp"
                android:textColor="@color/hl9"
                android:text="@string/place5txt"
                android:id="@+id/r1switch2"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
            <TextView
                android:textSize="13sp"
                android:layout_width="match_parent"
                android:layout_height="36dp"
                android:textColor="@color/hl9"
                android:text="@string/place2txt"
                android:id="@+id/r1switch3"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
        </LinearLayout>
        <LinearLayout
            android:background="@color/hl8"
            android:orientation="vertical"
            android:layout_width="150dp"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:gravity="center"
            android:layout_margin="1dp">
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="36dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r1b1on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_weight="1"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r1b1off" />
            </LinearLayout>
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="36dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r1b2on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_weight="1"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r1b2off" />
            </LinearLayout>
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="36dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r1b3on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r1b3off" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>

    <!--  -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:orientation="horizontal">
        <TextView
            android:layout_width="110dp"
            android:layout_height="match_parent"
            android:textSize="16sp"
            android:text="@string/room2txt"
            android:id="@+id/room2"
            android:layout_weight="1"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:gravity="center"
            android:background="@color/holotheme_color"
            android:textColor="@color/black"
            android:textStyle="bold"/>
        <TextView
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:textSize="13sp"
            android:text="@string/place1txt"
            android:textColor="@color/hl9"
            android:id="@+id/r2switch1"
            android:layout_weight="2"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:gravity="center|left"
            android:background="@color/hl8"/>
        <LinearLayout
            android:background="@color/hl8"
            android:orientation="horizontal"
            android:layout_width="150dp"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:gravity="center"
            android:layout_margin="1dp">
            <Button
                style="?android:attr/buttonStyleSmall"
                android:layout_width="wrap_content"
                android:layout_height="36dp"
                android:layout_weight="1"
                android:text=""
                android:id="@+id/r2b1on" />
            <Button
                style="?android:attr/buttonStyleSmall"
                android:layout_width="wrap_content"
                android:layout_weight="1"
                android:layout_height="36dp"
                android:text=""
                android:id="@+id/r2b1off" />
        </LinearLayout>
    </LinearLayout>

    <!--  -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:orientation="horizontal">
        <TextView
            android:layout_width="110dp"
            android:layout_height="match_parent"
            android:textSize="16sp"
            android:text="@string/room3txt"
            android:id="@+id/room3"
            android:layout_weight="1"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:textColor="@color/black"
            android:gravity="center"
            android:background="@color/holotheme_color"
            android:textStyle="bold"/>
        <TextView
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:textSize="13sp"
            android:textColor="@color/hl9"
            android:text="@string/place1txt"
            android:id="@+id/r3switch1"
            android:layout_weight="2"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:gravity="center|left"
            android:background="@color/hl8"
            android:clickable="true"/>
        <LinearLayout
            android:background="@color/hl8"
            android:orientation="horizontal"
            android:layout_width="150dp"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:gravity="center"
            android:layout_margin="1dp">
            <Button
                style="?android:attr/buttonStyleSmall"
                android:layout_width="wrap_content"
                android:layout_height="36dp"
                android:layout_weight="1"
                android:text=""
                android:id="@+id/r3b1on" />
            <Button
                style="?android:attr/buttonStyleSmall"
                android:layout_width="wrap_content"
                android:layout_height="36dp"
                android:layout_weight="1"
                android:text=""
                android:id="@+id/r3b1off" />
        </LinearLayout>
    </LinearLayout>

    <!--    -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:layout_width="110dp"
            android:layout_height="match_parent"
            android:textSize="16sp"
            android:text="@string/room4txt"
            android:id="@+id/room4"
            android:layout_weight="1"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:gravity="center"
            android:background="@color/holotheme_color"
            android:textColor="@color/black"
            android:textStyle="bold" />
        <LinearLayout
            android:orientation="vertical"
            android:background="@color/hl8"
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            android:layout_margin="1dp"
            android:gravity="center">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="37dp"
                android:text="@string/place6txt"
                android:textColor="@color/hl9"
                android:id="@+id/r4switch1"
                android:textSize="13sp"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="37dp"
                android:text="@string/place8txt"
                android:textColor="@color/hl9"
                android:id="@+id/r4switch3"
                android:textSize="13sp"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
            <TextView
                android:textSize="13sp"
                android:layout_width="match_parent"
                android:textColor="@color/hl9"
                android:layout_height="37dp"
                android:text="@string/place7txt"
                android:id="@+id/r4switch2"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
        </LinearLayout>
        <LinearLayout
            android:background="@color/hl8"
            android:orientation="vertical"
            android:layout_width="150dp"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:gravity="center"
            android:layout_margin="1dp">
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="37dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r4b1on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r4b1off" />
            </LinearLayout>
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="36dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r4b3on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r4b3off" />
            </LinearLayout>
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="36dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r4b2on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r4b2off" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>


    <!--  -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:layout_width="110dp"
            android:layout_height="match_parent"
            android:textSize="16sp"
            android:text="@string/room5txt"
            android:id="@+id/room5"
            android:layout_weight="1"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:gravity="center"
            android:textColor="@color/black"
            android:background="@color/holotheme_color"
            android:textStyle="bold" />
        <LinearLayout
            android:orientation="vertical"
            android:background="@color/hl8"
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            android:layout_margin="1dp"
            android:gravity="center">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="36dp"
                android:text="@string/place3txt"
                android:textColor="@color/hl9"
                android:id="@+id/r5switch1"
                android:textSize="13sp"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
            <TextView
                android:textSize="13sp"
                android:layout_width="match_parent"
                android:layout_height="37dp"
                android:textColor="@color/hl9"
                android:text="@string/place4txt"
                android:id="@+id/r5switch2"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
        </LinearLayout>
        <LinearLayout
            android:background="@color/hl8"
            android:orientation="vertical"
            android:layout_width="150dp"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:gravity="center"
            android:layout_margin="1dp">
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="36dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r5b1on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r5b1off" />
            </LinearLayout>
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="37dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r5b2on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r5b2off" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>

</LinearLayout>


Les méthodes OnClick sont liées aux boutons.
@Override
    public void onClick(View v) {
        // define the button switch that invoked the listener by id
        switch (v.getId()) {
            // Buttons room1 
            case R.id.r1b1on: // 
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room1txt)+" > "+r1sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch4url) + "on";
                new ParseTask().execute();
                break;

Le commutateur définit la vue ID de l'élément bouton, affiche un message TOAST à l'écran et envoie une requête HTTP au RPI via HttpURLConnection dans AsyncTask (appelez ParseTask (). Execute ();).
Interaction avec le backend
HttpURLConnection - une classe pour l'interaction via le protocole HTTP.
Classe asyncTask Méthode doInBackground - effectue des tâches lourdes dans un flux d'arrière-plan distinct et renvoie le résultat au flux d'interface utilisateur.
HttpURLConnection est exécuté dans la méthode doInBackground.
Cette technique se retrouve souvent sur Internet pour implémenter l'échange de données via le protocole HTTP.
webiopiurl = getString(R.string.ch4url) + "on";

Remplace une constante du fichier strings.xml dans les ressources du projet
<string name="ch4url">http://192.168.1.154:8000/macros/ch4/</string>

Ainsi, l'URL complète pour activer le canal 4 ressemble à ceci
http://192.168.1.154:8000/macros/ch4/on

// HTTP Query to backend in REST style
    private class ParseTask extends AsyncTask<Void, Void, String> {
        HttpURLConnection urlConnection = null;
        BufferedReader reader = null;
        String result = "";
        String BASIC_AUTH = "Basic "
                + Base64.encodeToString((getString(R.string.login) + ":" + getString(R.string.pwd)).getBytes(), Base64.NO_WRAP);

        @Override
        protected String doInBackground(Void... params) {
            //    REST 
            try {
                URL url = new URL(webiopiurl);
                urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("POST");
                urlConnection.setRequestProperty("Authorization", BASIC_AUTH);
                urlConnection.connect();
                //    backend webiopi
                InputStream inputStream = urlConnection.getInputStream();
                StringBuffer buffer = new StringBuffer();
                reader = new BufferedReader(new InputStreamReader(inputStream));
                String line;
                while ((line = reader.readLine()) != null) {
                    buffer.append(line);
                }
                result = buffer.toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }

code MainActivity.java TEL QUEL
package ru.bbq.smarthome_App;

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class MainActivity extends ActionBarActivity implements View.OnClickListener {
    // Add logger
    public static String LOG_TAG = "my_log";
    public static String webiopiurl = "";
    // switch buttons
    TextView r1sw1;
    TextView r1sw2;
    TextView r1sw3;
    TextView r2sw1;
    TextView r3sw1;
    TextView r4sw1;
    TextView r4sw2;
    TextView r4sw3;
    TextView r5sw1;
    TextView r5sw2;
    // ON OFF buttons
    Button r1b1on;
    Button r1b1off;
    Button r1b2on;
    Button r1b2off;
    Button r1b3on;
    Button r1b3off;
    Button r2b1on;
    Button r2b1off;
    Button r3b1on;
    Button r3b1off;
    Button r4b1on;
    Button r4b1off;
    Button r4b2on;
    Button r4b2off;
    Button r4b3on;
    Button r4b3off;
    Button r5b1on;
    Button r5b1off;
    Button r5b2on;
    Button r5b2off;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // find View-elements and buttons
        r1sw1 = (TextView) findViewById(R.id.r1switch1); // room1switch1
        r1sw2 = (TextView) findViewById(R.id.r1switch2); // room1switch2
        r1sw3 = (TextView) findViewById(R.id.r1switch3); // room1switch3
        r2sw1 = (TextView) findViewById(R.id.r2switch1); // room2switch1
        r3sw1 = (TextView) findViewById(R.id.r3switch1); // room3switch1
        r4sw1 = (TextView) findViewById(R.id.r4switch1); // room4switch1
        r4sw2 = (TextView) findViewById(R.id.r4switch2); // room4switch2
        r4sw3 = (TextView) findViewById(R.id.r4switch3); // room4switch3
        r5sw1 = (TextView) findViewById(R.id.r5switch1); // room5switch1
        r5sw2 = (TextView) findViewById(R.id.r5switch2); // room5switch2
        r1b1on = (Button) findViewById(R.id.r1b1on);    // room1 button1 ON
        r1b1off = (Button) findViewById(R.id.r1b1off);  // room1 button1 OFF
        r1b2on = (Button) findViewById(R.id.r1b2on);    // room1 button2 ON
        r1b2off = (Button) findViewById(R.id.r1b2off);  // room1 button2 OFF
        r1b3on = (Button) findViewById(R.id.r1b3on);    // room1 button3 ON
        r1b3off = (Button) findViewById(R.id.r1b3off);  // room1 button3 OFF
        r2b1on = (Button) findViewById(R.id.r2b1on);    // room2 button1 ON
        r2b1off = (Button) findViewById(R.id.r2b1off);  // room2 button1 OFF
        r3b1on = (Button) findViewById(R.id.r3b1on);    // room3 button1 ON
        r3b1off = (Button) findViewById(R.id.r3b1off);  // room3 button1 OFF
        r4b1on = (Button) findViewById(R.id.r4b1on);    // room4 button1 ON
        r4b1off = (Button) findViewById(R.id.r4b1off);  // room4 button1 OFF
        r4b2on = (Button) findViewById(R.id.r4b2on);    // room4 button2 ON
        r4b2off = (Button) findViewById(R.id.r4b2off);  // room4 button2 OFF
        r4b3on = (Button) findViewById(R.id.r4b3on);    // room4 button3 ON
        r4b3off = (Button) findViewById(R.id.r4b3off);  // room4 button3 OFF
        r5b1on = (Button) findViewById(R.id.r5b1on);    // room5 button1 ON
        r5b1off = (Button) findViewById(R.id.r5b1off);  // room5 button1 OFF
        r5b2on = (Button) findViewById(R.id.r5b2on);    // room5 button2 ON
        r5b2off = (Button) findViewById(R.id.r5b2off);  // room5 button2 OFF

        //assign listeners to buttons
        r1b1on.setOnClickListener(this);
        r1b1off.setOnClickListener(this);
        r1b2on.setOnClickListener(this);
        r1b2off.setOnClickListener(this);
        r1b3on.setOnClickListener(this);
        r1b3off.setOnClickListener(this);
        r2b1on.setOnClickListener(this);
        r2b1off.setOnClickListener(this);
        r3b1on.setOnClickListener(this);
        r3b1off.setOnClickListener(this);
        r4b1on.setOnClickListener(this);
        r4b1off.setOnClickListener(this);
        r4b2on.setOnClickListener(this);
        r4b2off.setOnClickListener(this);
        r4b3on.setOnClickListener(this);
        r4b3off.setOnClickListener(this);
        r5b1on.setOnClickListener(this);
        r5b1off.setOnClickListener(this);
        r5b2on.setOnClickListener(this);
        r5b2off.setOnClickListener(this);
    }

    // Define On ClickView method
    @Override
    public void onClick(View v) {
        // define the button switch that invoked the listener by id
        switch (v.getId()) {
            // Buttons room1 
            case R.id.r1b1on: // 
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room1txt)+" > "+r1sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch4url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r1b1off: // 
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room1txt)+" > "+r1sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch4url) + "off";
                new ParseTask().execute();
                break;
            case R.id.r1b2on: //  
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room1txt)+" > "+r1sw2.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch3url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r1b2off: //  
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room1txt)+" > "+r1sw2.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch3url) + "off";
                new ParseTask().execute();
                break;
            case R.id.r1b3on: // LED 
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room1txt)+" > "+r1sw3.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch2url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r1b3off: // LED 
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room1txt)+" > "+r1sw3.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch2url) + "off";
                new ParseTask().execute();
                break;
            // Buttons room2 
            case R.id.r2b1on:
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room2txt)+" > "+r2sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch6url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r2b1off:
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room2txt)+" > "+r2sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch6url) + "off";
                new ParseTask().execute();
                break;
            // Buttons room3 
            case R.id.r3b1on:
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room3txt)+" > "+r3sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch5url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r3b1off:
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room3txt)+" > "+r3sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch5url) + "off";
                new ParseTask().execute();
                break;
            // Buttons room4 bedroom
            case R.id.r4b1on: //    
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room4txt)+" > "+r4sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch8url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r4b1off: //    
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room4txt)+" > "+r4sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch8url) + "off";
                new ParseTask().execute();
                break;
            case R.id.r4b2on: //    
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room4txt)+" > "+r4sw2.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch7url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r4b2off: //    
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room4txt)+" > "+r4sw2.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch7url) + "off";
                new ParseTask().execute();
                break;
            case R.id.r4b3on: //   dimmer
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room4txt)+" > "+r4sw3.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch9url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r4b3off: //   dimmer
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room4txt)+" > "+r4sw3.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch9url) + "off";
                new ParseTask().execute();
                break;
            // Buttons room5 corridor
            case R.id.r5b1on:
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room5txt)+" > "+r5sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch1url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r5b1off:
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room5txt)+" > "+r5sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch1url) + "off";
                new ParseTask().execute();
                break;
            case R.id.r5b2on:
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room5txt)+" > "+r5sw2.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch0url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r5b2off:
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room5txt)+" > "+r5sw2.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch0url) + "off";
                new ParseTask().execute();
                break;
        }
    }

    // HTTP Query to backend in REST style
    private class ParseTask extends AsyncTask<Void, Void, String> {
        HttpURLConnection urlConnection = null;
        BufferedReader reader = null;
        String result = "";
        String BASIC_AUTH = "Basic "
                + Base64.encodeToString((getString(R.string.login) + ":" + getString(R.string.pwd)).getBytes(), Base64.NO_WRAP);
        @Override
        protected String doInBackground(Void... params) {
            //    REST 
            try {
                URL url = new URL(webiopiurl);
                urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("POST");
                urlConnection.setRequestProperty("Authorization", BASIC_AUTH);
                urlConnection.connect();
                //    backend webiopi
                InputStream inputStream = urlConnection.getInputStream();
                StringBuffer buffer = new StringBuffer();
                reader = new BufferedReader(new InputStreamReader(inputStream));
                String line;
                while ((line = reader.readLine()) != null) {
                    buffer.append(line);
                }
                result = buffer.toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }

        @Override
        protected void onPostExecute(String str) {
            super.onPostExecute(str);
            //  ,    plain text ( JSON)
            //    log
            Log.d(LOG_TAG, str);
            //  TOAST -   webiopi     MT1132
            Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT).show();
        }
    }

}



Trouvez et achetez des interrupteurs adaptés aux télécommandes


Sur la base du scénario d'éclairage, ce projet utilise des claviers NooLite et des boutons-poussoirs / commutateurs intégrés fixes, il est nécessaire de fournir la possibilité d'installer des commutateurs avec trois modules (boutons / touches), en préservant la conception des commutateurs (tous les commutateurs doivent avoir la même apparence).
Lors du choix des commutateurs, envisagez la possibilité de:
  • installation de deux à trois modules à l'appui de commutateurs
  • installation de modules de boutons et de claviers

Les interrupteurs bticino livinglight conviennent à ces conditions. Sur la photo ci-dessous, les modules assemblés avec la télécommande NooLite.


Bloc d'alimentation au plafond lors du débogage Débogage

sur site

Panneau électrique à faible courant situé à l'intérieur

Merci de votre attention Bonne journée!

Source: https://habr.com/ru/post/fr382689/


All Articles