KeyError: 392 upon trying to decode CAN message using dbc file? - python

I am trying to decode CAN messages from a device using the manufacturer's provided dbc file. I am using Python 3.8.5. To load/set up the dbc file, I have:
import can
import cantools
self.bus = can.interface.Bus('slcan0', bustype='socketcan',bitrate=250000)
listener = can.Listener()
listener.on_message_received = self.callback
self.dbc = cantools.database.load_file(dbc_file_path,strict=False) #need strict=False or it raises errors for overlapping signals for some reason
in the callback function I have:
def callback(self, can_msg):
decoded = self.dbc.decode_message(can_msg.arbitration_id, can_msg.data)
The script runs, but as soon as it receives a CAN message from the device, it gives me the following error:
Traceback (most recent call last):
File "/home/.local/lib/python3.8/site-packages/cantools/database/can/database.py", line 385, in decode_message
message = self._frame_id_to_message[frame_id_or_name]
KeyError: 392
Any idea what might be going wrong? I have googled and found similar errors on stack overflow, but they don't seem to be exactly the same, and the solutions they propose don't fix my issue.
Thanks!

I figured it out. The device was sending CAN messages with arbitration_ids that were not listed in the dbc file, and thus giving a Key Error. A Key Error is where you try to reference a Key in a Dictionary that does not exist. 392 was the unrecognized ID. I worked around this by adding a try/exception statement around my
decoded = self.dbc.decode_message(can_msg.arbitration_id, can_msg.data) line, and then investigating why the dbc file wasn't prepared for this particular message id.

Related

google ads api - "argument should be integer or bytes-like object, not 'str'"

I've been trying to follow the examples and documentation for the python ad_manager library for the google ads API, but I haven't been able to complete a successful request. I currently have my developer token, client_id, client_secret, and refresh_token in my google ads YAML file, but I'm constantly getting the error "argument should be integer or bytes-like object, not 'str'" when calling the function WaitForReport following the example code below. I was wondering if anyone had any advice on how I could tackle this issue.
import tempfile
# Import appropriate modules from the client library.
from googleads import ad_manager
from googleads import errors
def main(client):
# Initialize a DataDownloader.
report_downloader = client.GetDataDownloader(version='v202111')
# Create report job.
report_job = {
'reportQuery': {
'dimensions': ['COUNTRY_NAME', 'LINE_ITEM_ID', 'LINE_ITEM_NAME'],
'columns': ['UNIQUE_REACH_FREQUENCY', 'UNIQUE_REACH_IMPRESSIONS',
'UNIQUE_REACH'],
'dateRangeType': 'REACH_LIFETIME'
}
}
try:
# Run the report and wait for it to finish.
report_job_id = report_downloader.WaitForReport(report_job)
except errors.AdManagerReportError as e:
print('Failed to generate report. Error was: %s' % e)
# Change to your preferred export format.
export_format = 'CSV_DUMP'
report_file = tempfile.NamedTemporaryFile(suffix='.csv.gz', delete=False)
# Download report data.
report_downloader.DownloadReportToFile(
report_job_id, export_format, report_file)
report_file.close()
# Display results.
print('Report job with id "%s" downloaded to:\n%s' % (
report_job_id, report_file.name))
if __name__ == '__main__':
# Initialize client object.
ad_manager_client = ad_manager.AdManagerClient.LoadFromStorage()
main(ad_manager_client)
Edit:
Below is the stack trace:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/googleads/common.py", line 984, in MakeSoapRequest
return soap_service_method(
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/zeep/proxy.py", line 46, in __call__
return self._proxy._binding.send(
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/zeep/wsdl/bindings/soap.py", line 135, in send
return self.process_reply(client, operation_obj, response)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/zeep/wsdl/bindings/soap.py", line 229, in process_reply
return self.process_error(doc, operation)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/zeep/wsdl/bindings/soap.py", line 317, in process_error
raise Fault(
zeep.exceptions.Fault: Unknown fault occured
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "google_ads.py", line 72, in <module>
main(ad_manager_client)
File "google_ads.py", line 33, in main1
report_job_id = report_downloader.WaitForReport(report_job)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/googleads/ad_manager.py", line 784, in WaitForReport
report_job_id = service.runReportJob(report_job)['id']
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/googleads/common.py", line 989, in MakeSoapRequest
underlying_exception = e.detail.find(
TypeError: argument should be integer or bytes-like object, not 'str'
In your YAML file, do you have your account number in quotes? (either single or double?)
Additionally, I would highly recommend not going with this API if you have the option. It will be sunset in April and will no longer work. The newer google ads API (as opposed to the AdWords API) is available, stable and much easier to work with. The ad manager examples are good too.
The problem seems to be that zeep raises a WebFault which includes the returned XML response as a string in zeep.Fault.detail.
Somewhat counter-intuitive, this attribute is not a string, but a bytes sequence because zeep.wsdl.utils.etree_to_string calls etree.tostring() with encoding="utf-8" instead of encoding="unicode"—the latter would make sure it's a proper string.
googleads then tries to look for specific error strings inside the XML using find(), but even though find() is defined both on str and bytes, the type of the substring to look for needs to align.
Thus, in
underlying_exception = e.detail.find(
'{%s}ApiExceptionFault' % self._GetBindingNamespace())
bytes.find() is called with a str argument, causing the ValueError you experience.
I'd argue that zeep.wsdl.utils.etree_to_string() should be adjusted to actually return a str instead of bytes. You could try opening an issue on Zeep's Github repository.

How do you import json files to Blender?

I am Following Chris P's 'Visualize Real-world JSON Data in Blender (3D Chart Animation Nodes Tutorial)' on YouTube but I seem to have got stuck at the first hurdle of importing the data. I have followed his instructions completely and am unsure why the script keeps failing. I have attached his script, My script, my file location, my error message and a snap shot of his video. I am On windows OS, he is on Linux I'menter image description here not sure if that makes a difference. Here is the link to the video: https://www.youtube.com/watch?v=0aRjInmibSw&t=1055s THE TIMESTAMP FOR HIS CODE IS 6 min.
FILE NAME: Export.json
MY FILE LOCATION: C:\Users\Jordan\Downloads
MY CODE
import json
with open(r'C:/Users/Jordan/Downloads/Export.json','r') as f:
j=json.load(f)
print (j)
MY ERROR MESSAGE:
Traceback (most recent call last):
File "D:\Mixed Graphs\Blender json\3D Charts.blend\My Script", line 3, in <module>
OSError: [Errno 22] Invalid argument: '/C:/Users/Jordan/Downloads/Export'
Error: Python script failed, check the message in the system console
HIS CODE:
import json
with open('/Home/chris/downloads/tutorial1.json') as f:
json.load(f)
print (j)
Your problem seems to be that you're using "/"(slash) instead of ""(backslash) on Windows.
In addition you need to use two "\" as one backslash signals an escaping for the next character.
Fix therefore should be:
import json
with open(r'C:\\Users\\Jordan\\Downloads\\Export.json','r') as f:
j=json.load(f)
print (j)

Pycurl fails to upload after 301 redirection on Python3

I'm troubleshooting an existing python based Nagios plugin that uses PycURL to test that different actions can be taken on a remote WebDav service (GET,PUT,DELETE). We are having an issue when the service responds with a 301 redirection with the error "411 Length Required".
After checking the headers of the PUT requests for both the original service and to the redirected one, the latter is missing the "Content-Length" header, which is why this is failing. I haven't been able to find if there is an option that needs to be setup that is maybe needed for this to occur.
I am able to fix this in Python2 by adding the filesize using the option "INFILESIZE":
c.setopt(c.INFILESIZE, os.path.getsize(filepath))
The code looks like this:
#!/bin/python2
import pycurl
import os
filepath = '/tmp/testfile'
c = pycurl.Curl()
c.setopt(c.URL, 'http://remote_host.com/filename')
c.setopt(c.UPLOAD, 1)
file = open(filepath)
c.setopt(c.READDATA, file)
c.setopt(c.FOLLOWLOCATION, 1)
c.setopt(c.INFILESIZE, os.path.getsize(filepath))
c.perform()
c.close()
file.close()
However on Python3 (I've tried on 3.4, 3.6 and 3.7) the same code exits with error:
Traceback (most recent call last):
File "/usr/lib64/python3.7/codecs.py", line 322, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xda in position 2: invalid continuation byte
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
pycurl.error: (42, 'operation aborted by callback')
And I'm do not understand if this is an issue of with the reply from the server. But if I remove the INFILESIZE option, then it just fails with the 411 error mentioned above.
If anyone has any clue what I'm doing wrong, it would be greatly appreciated.
PycURL has different handling of files in Python 2 and Python 3. It sounds like you are running into this difference. See this manual page for the description of behavior: http://pycurl.io/docs/latest/files.html
It sounds like on Python 2, libcurl is able to perform a stat(2) call on the open file description to figure out its size. On Python 3 there is no file descriptor being passed but a function, hence stat(2) approach doesn't work and no file length is calculated for you.
To troubleshoot the Unicode decode error, on Python 2 change the code to use READFUNCTION rather than READDATA and see what error you get. If the server returns an error message in the response which is not valid utf-8, Python 3 may fail in the way you describe.

Python can't import WMI under special circumstance

I've created a standalone exe Windows service written in Python and built with pyInstaller. When I try to import wmi, an exception is thrown.
What's really baffling is that I can do it without a problem if running the code in a foreground exe, or a foreground python script, or a python script running as a background service via pythonservice.exe!
Why does it fail under this special circumstance of running as a service exe?
import wmi
Produces this error for me:
com_error: (-2147221020, 'Invalid syntax', None, None)
Here's the traceback:
Traceback (most recent call last):
File "<string>", line 43, in onRequest
File "C:\XXX\XXX\XXX.pyz", line 98, in XXX
File "C:\XXX\XXX\XXX.pyz", line 31, in XXX
File "C:\XXX\XXX\XXX.pyz", line 24, in XXX
File "C:\XXX\XXX\XXX.pyz", line 34, in XXX
File "C:\Program Files (x86)\PyInstaller-2.1\PyInstaller\loader\pyi_importers.py", line 270, in load_module
File "C:\XXX\XXX\out00-PYZ.pyz\wmi", line 157, in <module>
File "C:\XXX\XXX\out00-PYZ.pyz\win32com.client", line 72, in GetObject
File "C:\XXX\XXX\out00-PYZ.pyz\win32com.client", line 87, in Moniker
wmi.py line 157 has a global call to GetObject:
obj = GetObject ("winmgmts:")
win32com\client__init.py__ contains GetObject(), which ends up calling Moniker():
def GetObject(Pathname = None, Class = None, clsctx = None):
"""
Mimic VB's GetObject() function.
ob = GetObject(Class = "ProgID") or GetObject(Class = clsid) will
connect to an already running instance of the COM object.
ob = GetObject(r"c:\blah\blah\foo.xls") (aka the COM moniker syntax)
will return a ready to use Python wrapping of the required COM object.
Note: You must specifiy one or the other of these arguments. I know
this isn't pretty, but it is what VB does. Blech. If you don't
I'll throw ValueError at you. :)
This will most likely throw pythoncom.com_error if anything fails.
"""
if clsctx is None:
clsctx = pythoncom.CLSCTX_ALL
if (Pathname is None and Class is None) or \
(Pathname is not None and Class is not None):
raise ValueError("You must specify a value for Pathname or Class, but not both.")
if Class is not None:
return GetActiveObject(Class, clsctx)
else:
return Moniker(Pathname, clsctx)
The first line in Moniker(), i.e. MkParseDisplayName() is where the exception is encountered:
def Moniker(Pathname, clsctx = pythoncom.CLSCTX_ALL):
"""
Python friendly version of GetObject's moniker functionality.
"""
moniker, i, bindCtx = pythoncom.MkParseDisplayName(Pathname)
dispatch = moniker.BindToObject(bindCtx, None, pythoncom.IID_IDispatch)
return __WrapDispatch(dispatch, Pathname, clsctx=clsctx)
Note: I tried using
pythoncom.CoInitialize()
which apparently solves this import problem within a thread, but that didn't work...
I also face the same issue and I figure out this issue finally,
import pythoncom and CoInitialize pythoncom.CoInitialize (). They import wmi
import pythoncom
pythoncom.CoInitialize ()
import wmi
I tried solving this countless ways. In the end, I threw in the towel and had to just find a different means of achieving the same goals I had with wmi.
Apparently that invalid syntax error is thrown when trying to create an object with an invalid "moniker name", which can simply mean the service, application, etc. doesn't exist on the system. Under this circumstance "winmgmts" just can't be found at all it seems! And yes, I tried numerous variations on that moniker with additional specs, and I tried running the service under a different user account, etc.
Honestly I didn't dig in order to understand why this occurs.
Anyway, the below imports solved my problem - which was occurring only when ran from a Flask instance:
import os
import pythoncom
pythoncom.CoInitialize()
from win32com.client import GetObject
import wmi
The error "com_error: (-2147221020, 'Invalid syntax', None, None)" is exactly what popped up in my case so I came here after a long time of searching the web and voila:
Under this circumstance "winmgmts" just can't be found at all it
seems!
This was the correct hint for because i had just a typo , used "winmgmt:" without trailing 's'. So invalid sythax refers to the first methods parameter, not the python code itself. o_0 Unfortunately I can't find any reference which objects we can get with win32com.client.GetObject()... So if anybody has a hint to which params are "allowed" / should work, please port it here. :-)
kind regards
ChrisPHL

Error Handling in Python with SUDS

I have been trying to control a camera through a wsdl file using SUDS. I have got the code working but I want to place error handling into the script. I have tried different exceptions but am unable to get the script working. When I enter an invalid coordinate I get an error. The code I am using is below followed by the error I am recieving.
#!/home/build/Python-2.6.4/python
import suds
from suds.client import Client
####################################################################
#
# Python SUDS Script that controls movement of Camera
#
####################################################################
#
# Absolute Move Function
#
####################################################################
def absoluteMove():
# connects to WSDL file and stores location in variable 'client'
client = Client('http://file.wsdl')
# Create 'token' object to pass as an argument using the 'factory' namespace
token = client.factory.create('ns4:ReferenceToken')
print token
# Create 'dest' object to pass as an argument and values passed to this object
dest = client.factory.create('ns4:PTZVector')
dest.PanTilt._x=400
dest.PanTilt._y=0
dest.Zoom._x=1
print dest
# Create 'speed' object to pass as an argument and values passed to this object
speed = client.factory.create('ns4:PTZSpeed')
speed.PanTilt._x=0
speed.PanTilt._y=0
speed.Zoom._x=1
print speed
# 'AbsoluteMove' method invoked passing in the new values entered in the above objects
try:
result = client.service.AbsoluteMove(token, dest, speed)
except RuntimeError as detail:
print 'Handling run-time error:', detail
print "absoluteMove result ", result
result = absoluteMove()
The error is below:
No handlers could be found for logger "suds.client"
Traceback (most recent call last):
File "ptztest.py", line 48, in <module>
if __name__ == '__main__': result = absoluteMove()
File "ptztest.py", line 42, in absoluteMove
result = client.service.AbsoluteMove(token, dest, speed)
File "build/bdist.linux-i686/egg/suds/client.py", line 537, in __call__
File "build/bdist.linux-i686/egg/suds/client.py", line 597, in invoke
File "build/bdist.linux-i686/egg/suds/client.py", line 632, in send
File "build/bdist.linux-i686/egg/suds/client.py", line 683, in failed
File "build/bdist.linux-i686/egg/suds/bindings/binding.py", line 235, in get_fault
suds.WebFault: Server raised fault: 'Error setting requested pan'
I am not sure which exception I should be using here. Does anyone know how to catch this error. The x coordinate with the value 400 is in degree's that is why the error happens.
Thanks
Okay I have found the solution. In SUDS if you enter:
faults=False
into the client definition, this catches faults and gives the reason why the fault happened. The line should read:
client = Client('http://file.wsdl', faults=False)
The post that I have marked as the correct answer also is able to catch that a problem has happened.
Thanks all
If you handled all exceptions and errors in your code and your code is working fine but still you are getting below message with your correct output.
Msg : "No handlers could be found for logger suds.client "
Then a simple solution is to add this line
logging.getLogger('suds.client').setLevel(logging.CRITICAL)
in yourclient.py file just after all import statement.
If you want to catch that exception you should put
try:
result = client.service.AbsoluteMove(token, dest, speed)
except suds.WebFault as detail:
...
You need to catch suds.WebFault by the looks of that traceback. The error itself seems legitimate, IE, your requests are being executed correctly, but perhaps your parameters are wrong in the given context.
I believe you refer to a harmless diagnostic message in your comment. I could suppress messages from suds calling logging.error() by assigning logging.INFO to basicConfig and logging.CRITICAL to suds.client.
https://fedorahosted.org/suds/wiki/Documentation

Categories

Resources