/connector/ApiConnector.py
https://gitlab.com/farmee-public/farmee-controller-rpi · Python · 269 lines · 188 code · 52 blank · 29 comment · 37 complexity · 45f83bbe6d9372b3e1639b88eb8a27fe MD5 · raw file
- # -*- coding: utf-8 -*-
- #
- # farmee controller
- # Copyright (C) 2018 farmee GmbH
- #
- # This file is part of farmee controller.
- #
- # farmee controller 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 3 of the License, or
- # (at your option) any later version.
- #
- # farmee controller 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 farmee controller. If not, see <http://www.gnu.org/licenses/>.
- from __future__ import unicode_literals
- import json
- import logging
- import socket
- import urllib2
- import warnings
- from urllib2 import URLError, HTTPError
- import ssl
- class ApiConnector(object):
-
- def __init__(self):
- self.port = 443
- self.token = ''
- self.baseAddress = ''
- self.httpMode = 'https'
- self.timeout = 5.0
-
- def setTimeout(self, t):
- self.timeout = t
- return
-
- def init(self, baseAddress, apikey, port=443):
- self.baseAddress = baseAddress
- self.port = port
- logging.info("connecting to " + baseAddress + ":" + port)
- # authorize
- url = self.httpMode + '://' + self.baseAddress + ':' + str(port) + '/v1/oauth/token?apikey=' + apikey
- logging.debug( "call %s", url )
- headers = { "Content-Type": "application/json" }
- req = urllib2.Request( url=url, headers=headers )
- token = False
- try:
- content = urllib2.urlopen(req, timeout=self.timeout ).read()
- logging.info("content %s", content)
- jsonObject = json.loads( content )
- token = jsonObject["access_token"]
- except HTTPError as e:
- logging.warning( 'http error %s', e.code)
- except URLError as e:
- logging.warning( 'url error %s', e.reason)
- except socket.timeout as e:
- logging.warning( 'socket timeout' )
- if( token == False ):
- logging.error( 'authorization failed' )
- return False
- self.accessToken = token
- return True
- def __getApiUrl(self, request=''):
- return self.httpMode + '://' + self.baseAddress + ":" + str(self.port) + '/v1/' + request + '?access_token=' + self.accessToken
-
- def testConnection(self):
- connected = False
- try:
- urllib2.urlopen(self.__getApiUrl('configurations'), timeout=self.timeout).read()
- connected = True
- except (URLError, socket.timeout) as e:
- logging.warning('Unable to connect to farmee server')
- logging.warning(e)
-
- return connected
- def registerUnit(self,uuid,platform,ip,type,version):
- """
- Registers the Unit in the API and gets the Unit ID for further Calls
- """
- url = self.__getApiUrl('units/register')
- logging.debug( 'call ' + url )
- unitId = False
- data = json.dumps( { 'uuid': uuid, 'operatingSystem': platform,
- 'ipAddress': ip, 'controllerType': type,
- 'controllerVersion': version } )
- headers = { "Content-Type": "application/json" }
- req = urllib2.Request( url=url, data=data, headers=headers )
- try:
- content = urllib2.urlopen(req, timeout=self.timeout ).read()
- logging.info("content %s", content)
- jsonObject = json.loads( content )
- unit = jsonObject[0]
- unitId = unit["id"]
- except HTTPError as e:
- logging.warning( 'http error %s', e.code)
- except URLError as e:
- logging.warning( 'url error %s', e.reason)
- except socket.timeout as e:
- logging.warning( 'socket timeout' )
- return unitId
- # sends the current unitstate to the controlserver and gets the new configuration
- def updateState(self,data):
- url = self.__getApiUrl('units/sendstate')
- logging.debug( 'call ' + url )
- logging.debug("data %s", data )
-
- config = False
-
- data = json.dumps( data )
- headers = { "Content-Type": "application/json" }
- req = urllib2.Request( url=url, data=data, headers=headers )
-
- try:
- content = urllib2.urlopen(req, timeout=self.timeout ).read()
- logging.info("content %s", content)
- jsonObject = json.loads( content )
- config = jsonObject["configuration"]
- except HTTPError as e:
- logging.warning( 'http error %s', e.code)
- except URLError as e:
- logging.warning( 'url error %s', e.reason)
- except socket.timeout as e:
- logging.warning( 'socket timeout' )
-
- return config
- def getConfigurations(self,unitId):
- url = self.__getApiUrl( 'units/' + str(unitId) + '/configurations')
- logging.debug('Calling %s', url)
- req = urllib2.Request(url=url)
- try:
- content = urllib2.urlopen(req, timeout=self.timeout).read()
- logging.info("Retrieving sensor/actor configuration")
- logging.debug(content)
- return json.loads(content)
- except HTTPError as e:
- logging.warning('http error %s', e.code)
- except URLError as e:
- logging.warning('url error %s', e.reason)
- except socket.timeout as e:
- logging.warning('socket timeout')
- return False
- def saveSensor(self, sensor):
- url = self.__getApiUrl('sensors')
- logging.debug('Calling %s', url)
- headers = {"Content-Type": "application/json"}
- data = {
- 'name': sensor['name'],
- 'type': sensor['type'],
- 'config': sensor['config']
- }
- # update existing sensor if possible
- if 'id' in sensor:
- data['id'] = sensor['id']
- req = urllib2.Request(url=url, data=json.dumps(data), headers=headers)
- try:
- content = urllib2.urlopen(req, timeout=self.timeout).read()
- logging.info("Saving sensor %s", content)
- return json.loads(content)
- except HTTPError as e:
- logging.warning('http error %s', e.code)
- except URLError as e:
- logging.warning('url error %s', e.reason)
- except socket.timeout as e:
- logging.warning('socket timeout')
- def deleteSensor(self, sensor_id):
- url = self.__getApiUrl('sensors/{}'.format(sensor_id))
- logging.debug('Calling %s', url)
- req = urllib2.Request(url=url)
- req.get_method = lambda: 'DELETE'
- try:
- response = urllib2.urlopen(req, timeout=self.timeout).read()
- logging.info("Deleting sensor %s", response)
- return json.loads(response)
- except HTTPError as e:
- logging.warning('http error %s', e.code)
- except URLError as e:
- logging.warning('url error %s', e.reason)
- except socket.timeout as e:
- logging.warning('socket timeout')
- def saveActor(self, actor):
- url = self.__getApiUrl('actors')
- logging.debug('Calling %s', url)
- headers = {"Content-Type": "application/json"}
- data = {
- 'name': actor['name'],
- 'type': actor['type'],
- 'config': actor['config']
- }
- # update existing sensor if possible
- if 'id' in actor:
- data['id'] = actor['id']
- req = urllib2.Request(url=url, data=json.dumps(data), headers=headers)
- try:
- content = urllib2.urlopen(req, timeout=self.timeout).read()
- logging.info("Saving actor %s", content)
- return json.loads(content)
- except HTTPError as e:
- logging.warning('http error %s', e.code)
- except URLError as e:
- logging.warning('url error %s', e.reason)
- except socket.timeout as e:
- logging.warning('socket timeout')
- def deleteActor(self, actor_id):
- url = self.__getApiUrl('actors/{}'.format(actor_id))
- logging.debug('Calling %s', url)
- req = urllib2.Request(url=url)
- req.get_method = lambda: 'DELETE'
- try:
- response = urllib2.urlopen(req, timeout=self.timeout).read()
- logging.info("Deleting actor %s", response)
- return json.loads(response)
- except HTTPError as e:
- logging.warning('http error %s', e.code)
- except URLError as e:
- logging.warning('url error %s', e.reason)
- except socket.timeout as e:
- logging.warning('socket timeout')
- def sendData(self, datatype, data):
- """
- Sends additional data which should not be processed via the unitstate call (e.g. images)
- """
- warnings.warn("Sending additional data packages is currently not implemented")