How do we get output channel values of an ardupilot from dronekit-python?
We can get input channels from vehicle.channels but I couldn't find anything similar for output channels.
EDIT:
from time import sleep
from dronekit import connect
import dronekit_sitl
sitl = dronekit_sitl.start_default()
connection_string = sitl.connection_string()
vehicle = connect(connection_string,wait_ready=True)
while not vehicle.is_armable:
sleep(1)
print"Initializing"
vehicle.armed = True
while not vehicle.armed:
print "Arming"
sleep(1)
print "Armed"
#vehicle.on_attribute('ch1out')
def ch1out_listener(self, name, msg):
print '%s attribute is: %s' % (name, msg)
for i in range(1000,2000,100):
vehicle.channels.overrides['3']=i
sleep(1)
vehicle.close()
It should print ch1out everytime I update channel 3 but it is not.
I assume what you mean output channels is this 'ch1out','ch2out' value and so on.
To get that value you can simply just using an attribute listener like this
#vehicle.on_attribute('ch1out')
def ch1out_listener(self, name, msg):
print '%s attribute is: %s' % (name, msg)
This function essentially just print the 'ch1out' value everytime it changes, you can just modify it accordingly. You can read more about this at here Observing attribute changes.
But if you want to access the output channel value directly from the vehicle object like the input channel or other attribute.
(Ex: vehicle.channels, vehicle.mode)
You can add the output channel to the vehicle object by following this example provided by the Dronekit-Python documentation Create Attribute in App.
The way to do this is to create a new vehicle class. You can do this following the example given in dronekit.
Then connect using your new class:
vehicle = connect(connection_string, wait_ready=True,
vehicle_class=MyVehicle) def raw_servo_callback(self, attr_name,
value):
print(value)
vehicle.add_attribute_listener('raw_servo', raw_servo_callback)
Here is the class for the above example:
from dronekit import Vehicle
class RawSERVO(object):
"""
:param ch1out: servo1
:param ch3out: servo3
"""
def __init__(self, ch1out=None, ch3out=None):
"""
RawIMU object constructor.
"""
self.ch1out = ch1out
self.ch3out = ch3out
def __str__(self):
"""
String representation used to print
"""
return "{},{}".format(self.ch1out, self.ch3out)
class MyVehicle(Vehicle):
def __init__(self, *args):
super(MyVehicle, self).__init__(*args)
# Create an Vehicle.raw_servo object with initial values set to None.
self._raw_servo = RawSERVO()
# Create a message listener using the decorator.
#self.on_message('SERVO_OUTPUT_RAW')
def listener(self, name, message):
"""
The listener is called for messages that contain the string specified in the decorator,
passing the vehicle, message name, and the message.
The listener writes the message to the (newly attached) ``vehicle.raw_servo`` object
and notifies observers.
"""
self._raw_servo.ch1out=message.servo1_raw
self._raw_servo.ch3out=message.servo3_raw
# Notify all observers of new message (with new value)
# Note that argument `cache=False` by default so listeners
# are updated with every new message
self.notify_attribute_listeners('raw_servo', self._raw_servo)
#property
def raw_servo(self):
return self._raw_servo
This is the solution if you are using PixHawk and Raspberry Pi connected through UART Issue source. You can configure this one using Mission Planner.
Output Channels read to none when both Serial1 and Serial2 Protocols are set to 2. I set both protocols to 1 and I set my Serial 1 baud to 57 and Serial 2 baud to 921. Had the UART connected through Telem 2.
Hope it helps!
Related
I'm trying to automatically fill in a specific charblock on a streamfield I have created on save and I can get it to change but not save because when the page refreshes the new data is not there.
def save(self, *args, **kwargs):
if kwargs.get('update_fields'):
if self.auto_update:
for product in self.product_details.raw_data:
product_name = product['value']['product_name']
product_url = product['value']['product_url']
# I'm trying to set the field data here
product['value']['product_snippet_url'] = 'Test'
# when I print, I see the 'Test' value in the dict
print(product)
else:
# Do stuff on publish()
pass
return super().save(*args, **kwargs)
# Streamfield Block
class ProductNameAndUrlBlock(blocks.StructBlock):
product_name = blocks.CharBlock(required=True, help_text='Add product name')
product_url = blocks.URLBlock(required=True, help_text='Add Product URL')
product_snippet_url = blocks.CharBlock(required=False, help_text='Link to snippet')
The above code is for testing purposes, my end goal is to insert the url of the related snippet there and then use JS to turn it into a button so when someone clicks on it, it links to the snippet page.
Writing back to the stream's raw_data property will not reliably save the data. raw_data is a "backup" copy of the data as retrieved from the database, in a simplified format - for example, a PageChooserBlock value is stored there as a plain ID rather than a Page object. Once data is read or written through the stream's standard methods (e.g. looping over for block in self.product_details or writing self.product_details[0] = ...), the raw_data entry is treated as stale and not looked at again.
The correct approach is to read and write the stream itself as a list, rather than going through raw_data:
for product in self.product_details:
product_name = product.value['product_name']
product_url = product.value['product_url']
# I'm trying to set the field data here
product.value['product_snippet_url'] = 'Test'
I start python and TDD, I would like to know how to run behave steps with python and scenarios table for the two scenarios below:
The program ask a user to enter data (humididity level and temperature) and it prints those data.
For the first scenario, user fill out data and the program prints those data (normal case). I just want to check if there is data input
For the second scenario, if user fill out "text" the program return a syntax error.I would like to check the data type in #then steps
The problem is that when I run steps with behave command it asks me to enter data but I want the program uses data table in gherkin scenarios. Can you help please?
gherkin scenario below:
Feature: As a user I want fill out humidex data to visualize it
Scenario: user fill out humidex data correctly
Given a user
When user fill out humidexdata
|humidity|temperature|
|50% |28C° |
Then user visualize
|humidity|temperature|
|50% |28C° |
Scenario: user fill out humidex data with text
Given a user
When user fill out humidexdata
|humidity |temperature|
|lorem ipsum|lorem ipsum|
Then user visualize a syntax error "data syntax is wrong retry"
step implementations with behave:
from behave import *
from fillouthumidexdata import *
#given(u'a user')
def step_impl(context):
context.user = User()
#when(u'user fill out humidexdata')
def step_impl(context):
context.user.fillout_humidexData()
#then(u'user visualize')
def step_impl(context):
context.user.visualize_humidexData()
python code:
class User():
def __init__(self):
self.humidity = []
self.temperature =[]
def fillout_humidexData(self):
print("Enter humidity level (%)")
input(self.humidity)
print("Enter temperature (C°)")
input(self.temperature)
def visualize_humidexData(self):
print(self.humidity)
print(self.temperature)
I am not sure why you need actually separate User class as all of that can be done in simple steps, but following this approach I would change first a bit the User class at least to:
class User():
def __init__(self):
self.humidity = 0
self.temperature = 0
def fillout_humidexData(self, humidity, temperature):
self.humidity = humidity
self.temperature = temperature
def visualize_humidexData(self):
print(f'humidity: {self.humidity}')
print(f'temperature: {self.temperature}')
And then use the following steps:
from behave import step, given, when, then
from fillouthumidexdata import *
#given(u'a user')
def step_impl(context):
context.user = User()
#when(u'user fill out humidexdata')
def step_impl(context):
humidity, temperature = context.table.rows[0]
context.user.fillout_humidexData(humidity, temperature)
#then(u'user visualize')
def step_impl(context):
context.user.visualize_humidexData()
rows[0] should give you values from first row in your setup table(2 values from 2 columns).
I think this should work, but I am not sure if this is what you want.
I have an API to get list of ids, name, data etc. (TestCase name GET-APIs_OrderdByID_ASC)
I want to transfer those IDs to other following TestCases in same TestSuite or other TestSuite.
In SOAPUI, Property Transfer works within TestSteps in same TestCase. (Using OpenSource version). I need to transfer the property value among different TestCases / TestSuites.
Below is the code that I can extract ids from one testCase and also name of testCases/testSteps where I want to transfer.
import com.eviware.soapui.impl.wsdl.teststeps.*
import com.eviware.soapui.support.types.StringToStringMap
import groovy.json.*
def project = context.testCase.testSuite.project
def TestSuite = project.getTestSuiteByName("APIs")
def TestCase = TestSuite.getTestCaseList()
def TestStep = TestCase.testStepList
def request = testRunner.testCase.getTestStepByName("List_of_APIs_OrderByID_ASC")
def response = request.getPropertyValue("Response")
def JsonSlurperResponse = new JsonSlurper().parseText(response)
def Steps = TestStep.drop(3)
log.info JsonSlurperResponse.data.id
def id = JsonSlurperResponse.data.id
Steps.each {
it.getAt(0).setPropertyValue("apiId", id.toString())
log.info it.getAt(0).name
}
If I run above code, all the array values of id [1, 2, 10, 11, 12, 13, 14, 15, 16, 17, 18] are set to each of the following testSteps
I looked some other SO questions
Property transfer in SOAPUI using groovy script
groovy-script-and-property-transfer-in-soapui
Can anyone help me out. :-)
I have done something with datasinks as Leminou suggests.
Datasinks are a good solution for this. In test A, create a datasink step to persist the values of interest. Then in the target step, use a data source step, which links to the file generated by the datasink earlier.
The data sink can be configured to append after each test or start afresh.
If you're struggling to tease out the values for the datasink, create a groovy step that returns the single value you want, then in the datasink step, invoke the groovy.
Sounds a little convoluted, but it works.
You can use project level properties or testSuiteLevel properties or testCase Properties.
This way you can achieve the same thing that you get from Property Transfer step but in a different way.
Write a groovy step in the source test case to setProperty(save values you want to use later)
testRunner.testCase.setPropertyValue("TCaseProp", "TestCase")
testRunner.testCase.testSuite.setPropertyValue("TSuiteProp","TestSuite")
testRunner.testCase.testSuite.project.setPropertyValue("ProjectLevel","ProjectLevelProperty")
"TCaseProp" is the name of the property. you can give any name
"TestCase" is the value you want to store. You can extract this value and use a variable
for example
def val="9000"
testRunner.testCase.setPropertyValue("TCaseProp", val)
You can use that property in other case of same suite. If you want to use across different suites you can define project level property
use the below syntax in target testcase request
${#Project#ProjectLevel}
${#TestCase#TCaseProp}
${#TestSuite#TCaseProp}
<convertCurrency>${#TestSuite#TCaseProp}</ssp:SystemUsername>
System will automatically replace the property value in above request
https://www.soapui.org/scripting-properties/tips-tricks.html <-- Helpful link which can explain in detail about property transfer
Well the following Script works.
Just to change as
Steps.each { s ->
id.each { i ->
s.getAt(0).setPropertyValue("apiId", i.toString())
}
}
Here id is a ArrayList type. So We can loop through the List.
PS: We can do the same using for loop.
I have a model M contains three manytomanyfields(a,b,c) to three different models in django.
class M (models.Model):
name = models.CharField()
a = models.ManyToManyField(A)
b = models.ManyToManyField(B)
c = models.ManyToManyField(C)
Now, I want to handle any changes on my model M and send an HttpRequest to an url correspondingly.
as you know in post-save signal of model M the values of attributes for a,b and c are not set yet because they will be set when saving model M has been finished.(the rule of ManyToManyField)
I write a single handler for my model to handle any changes(either create a new instance or update a field/fields)
#receiver(post_save, sender=M)
#receiver(m2m_changed, sender=M.a.through)
#receiver(m2m_changed, sender=M.b.through)
#receiver(m2m_changed, sender=M.c.through)
def M_changes_handler(sender, **kwargs):
is_instance_set_compeletly(kwargs['instance']):
#send_and_HttpRequest(url, data = instance)
def is_instance_set_compeletly(kwargs['instance']):
if M.a.all() is not None and M.b.all() is not None and
M.c.all()is not None
flag = True
else:
flag = False
return flag
Now consider an update request (which changes all fields) on model M will send signals for all fields a,b and c; so three httpRequests would send to my sender with three different versions of instance! on the other hand when user just changes a field for example b of the model M this function will send only one httpRequest.
I want to handle this problem dynamically and just send one request per ANY TYPE of CHANGE on my model M.
I was wondering if somebody could help me :)
*Note the code above is just a draft and may contains syntax error so ignore them ;)
Update: My problem solved!
The process of saving a model containing m2mfields is interesting!
First of all the fields of M which are not m2m fields type e.g. are char field, foreign key or etc. had been set before calling post_save. So in post_save their values are updated
Although m2mfields wont be set till the saving of the model would be finished. Then m2mchange signals called to set m2mfields
The only way to have an updated version of your model is to overriding form save in admin.py because the "form save" will be called after finishing all m2mfields have been set
Solution:
For all stack-overflow users and Dear Blake Gibbs
If a model contains manytomany fields and you want to access all the data of a saved record, you cannot access those m2m fields because they will save after finishing the process of saving model(consider M in my example), then assign that Id to other self-created m2m table to bind that Id to m2m fields (e.g. A in my example). so overriding the save method of a model in admin.py does not work in this case.
I simply override the save function of my form in Forms.py
class MForm(forms.ModelForm):
class Meta:
model = M
exclude = []
def save(self, commit=True):
query = ""
old_instance = super(MForm, self).save(commit=False)# if you need the old instance
#otherwise return super(MForm, self).save(commit=True)
instance = super(MForm,self).save(commit=True)
in this case the "instance" is really saved completely and you can access m2m fields by using ".all()"
hope it helped!
you can hold previously instance of M and in post_save with new M check field have changed according to that you can send request.
I hope I didn't miss any topic that could answer my problem. I'm here now because I'm terribly frustrated and tired with the following task:
- I have a Spreasheet with Drive.Google with lots of data in it
- I would like to create an application with wxPython that would pull data from this spreeadsheet (in the most easy way possible)
- Would also like to get multiple data from a user who will access this application through a nice interface (panel aka window)
- The multiple data introduced by the user should be able to work with the data pulled out from the Spreasheet. For example to see if the data introduced by the user is in the Spreadsheet or not and also some other operations with the next data introduced by the user.
- Finally and most importantly show the results to the user (later I would also like to add some functions to save somehow the results)
I hope I managed to express clearly what I would like to do. Now I'm new to Google API's, Python adn wxPython, but I have experience with C++ , php, html .
I've spent 2 weeks now with discovering Drive.Google and learning Python and wxPython. I did follow all tuturials on these, made my notes, read tones of stackoverflow questions-answers, wiki.wxpython.org etc. I learn every single day and I can do now many things separately but to have all functions like I described above I just couldn't work out how to do. At least please orient me in the direction. Awfel lot of times I spend hours doing examples and getting nowhere. I have Python, wxPython extention, GoogleAppEngine Launcher and even pyCharm demo. Please be kind. This is my first question ever.
here's the mess I made so far combining relevant examples:
import wx
import gdata.docs
import gdata.docs.service
import gdata.spreadsheet.service
import re, os
class Form(wx.Panel):
def __init__(self, *args, **kwargs):
super(Form, self).__init__(*args, **kwargs)
self.createControls()
self.bindEvents()
self.doLayout()
self.spreasht()
def createControls(self):
self.logger = wx.TextCtrl(self, style=wx.TE_MULTILINE|wx.TE_READONLY)
self.saveButton = wx.Button(self, label="Elvegzes")
self.nameLabel = wx.StaticText(self, label="type Name1:")
self.nameTextCtrl = wx.TextCtrl(self, value="type here")
self.name2Label = wx.StaticText(self, label="type Name2:")
self.name2TextCtrl = wx.TextCtrl(self, value="type here")
def bindEvents(self):
for control, event, handler in \
[(self.saveButton, wx.EVT_BUTTON, self.onSave),
(self.nameTextCtrl, wx.EVT_TEXT, self.onNameEntered),
(self.nameTextCtrl, wx.EVT_CHAR, self.onNameChanged)]:
control.Bind(event, handler)
def doLayout(self):
raise NotImplementedError
def spreadsht(self):
gd_client = gdata.spreadsheet.service.SpreadsheetsService()
gd_client.email = 'my email address'
gd_client.password = 'my password to it'
gd_client.source = 'payne.org-example-1'
gd_client.ProgrammaticLogin()
q = gdata.spreadsheet.service.DocumentQuery()
q['title'] = 'stationcenter'
q['title-exact'] = 'true'
feed = gd_client.GetSpreadsheetsFeed(query=q)
spreadsheet_id = feed.entry[0].id.text.rsplit('/',1)[1]
feed = gd_client.GetWorksheetsFeed(spreadsheet_id)
worksheet_id = feed.entry[0].id.text.rsplit('/',1)[1]
al1 = raw_input('Name1: ')
print al1
al2 = raw_input('Name2: ')
print al2
rows = gd_client.GetListFeed(spreadsheet_id, worksheet_id).entry
for row in rows:
for key in row.custom:
if al1 == row.custom[key].text:
print ' %s: %s' % (key, row.custom[key].text)
def onColorchanged(self, event):
self.__log('User wants color: %s'%self.colors[event.GetInt()])
def onReferrerEntered(self, event):
self.__log('User entered referrer: %s'%event.GetString())
def onSave(self,event):
self.__log('User clicked on button with id %d'%event.GetId())
def onNameEntered(self, event):
self.__log('User entered name: %s'%event.GetString())
def onNameChanged(self, event):
self.__log('User typed character: %d'%event.GetKeyCode())
event.Skip()
def onInsuranceChanged(self, event):
self.__log('User wants insurance: %s'%bool(event.Checked()))
# Helper method(s):
def __log(self, message):
''' Private method to append a string to the logger text
control. '''
self.logger.AppendText('%s\n'%message)
class FormWithSizer(Form):
def doLayout(self):
''' Layout the controls by means of sizers. '''
boxSizer = wx.BoxSizer(orient=wx.HORIZONTAL)
gridSizer = wx.FlexGridSizer(rows=5, cols=2, vgap=10, hgap=10)
# Prepare some reusable arguments for calling sizer.Add():
expandOption = dict(flag=wx.EXPAND)
noOptions = dict()
emptySpace = ((0, 0), noOptions)
# Add the controls to the sizers:
for control, options in \
[(self.nameLabel, noOptions),
(self.nameTextCtrl, expandOption),
(self.allomas2Label, noOptions),
(self.allomas2TextCtrl, expandOption),
emptySpace,
(self.saveButton, dict(flag=wx.ALIGN_CENTER))]:
gridSizer.Add(control, **options)
for control, options in \
[(gridSizer, dict(border=5, flag=wx.ALL)),
(self.logger, dict(border=5, flag=wx.ALL|wx.EXPAND,
proportion=1))]:
boxSizer.Add(control, **options)
self.SetSizerAndFit(boxSizer)
class FrameWithForms(wx.Frame):
def __init__(self, *args, **kwargs):
super(FrameWithForms, self).__init__(*args, **kwargs)
notebook = wx.Notebook(self)
form2 = FormWithSizer(notebook)
notebook.AddPage(form2, 'CALTH')
self.SetClientSize(notebook.GetBestSize())
if __name__ == '__main__':
app = wx.App(0)
frame = FrameWithForms(None, title='Relevant title˝')
frame.Show()
app.MainLoop()
THANK YOU AGAIN!!!!!!!!!!!
First, make sure you can download the data you want with just Python. Then create a wxPython GUI with a single button. In that button's handler, have it call the script that can download the data you want.
If that causes your GUI to become unresponsive, then you'll need to use a thread to do the downloading. I recommend the following articles if that's the case:
http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/
http://wiki.wxpython.org/LongRunningTasks
Okay, so now you have the data downloading appropriately. Now you add a grid widget or a listctrl / object list view widget. Pick one of those. I prefer object list view, which you can read about here. Then in your button handler you can call your downloader script or thread and when that's done, you can load the widget with that data. If you're using a thread, then the thread will have to call the next step (i.e. the widget loading bit).
Now you should have your data displayed. All that's left is making it look pretty and maybe putting the downloading part into a menu item.